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 WithValue expressions (i.e. ReflectedDefinition(true)) #142

Closed 0x53A closed 5 years ago

0x53A commented 5 years ago

I want to run "isomorphic" unit tests between .NET and Fable.

Fable doesn't support Quotations, so I had the idea to use ReflectedDefinitionAttribute - that way I can write my code without the <@ @> and it should work either as a expression or just as a normal parameter.

type T =
#if !FABLE_COMPILER
    static member test ([<ReflectedDefinition(true)>] x:Microsoft.FSharp.Quotations.Expr<bool>) = Swensen.Unquote.Assertions.test x
#else
    static member test x = Fable.Core.Testing.Assert.AreEqual(true, x)
#endif

[<EntryPoint>]
let main argv =

    let fn1 = (fun _ ->
        let state = 1        
        T.test ((state = 1))
    )

    let fn2 = (fun _ ->
        let state = 1
        Swensen.Unquote.Assertions.test <@ state = 1 @>
    )

    fn2() // works
    fn1() // fails
    0

But this seems to prouce a slightly different expression tree and then fails:

this expression should not be possible: WithValue (true, Value (true))

Unhandled Exception: Swensen.Unquote.AssertionFailedException: Test failed:

WithValue (true, Call (None, op_Equality, [ValueWithName (1, state), Value (1)]))
WithValue (true, Value (true))
System.Exception: this expression should not be possible: WithValue (true, Value (true))
   at Swensen.Unquote.Evaluation.eval(FSharpList`1 env, FSharpExpr expr)
   at Swensen.Unquote.Reduction.reduce(FSharpList`1 env, FSharpExpr expr)
   at Swensen.Unquote.Reduction.loop@126(FSharpList`1 env, FSharpExpr expr, FSharpList`1 acc)

   at Program.T.test(FSharpExpr`1 x) in C:\Users\rieluk\Source\Repos\unquoteRepro\unquoteRepro\Program.fs:line 6
   at Program.fn1@12T.Invoke(a _arg1) in C:\Users\rieluk\Source\Repos\unquoteRepro\unquoteRepro\Program.fs:line 14
   at Program.main(String[] argv) in C:\Users\rieluk\Source\Repos\unquoteRepro\unquoteRepro\Program.fs:line 24
stephen-swensen commented 5 years ago

Thanks for reporting. At first glance it looks more like an issue with decompiling the ValueWithName quoted expression than with working with ReflectedDefinition quotations in general.

Also: cool idea for running "isomorphic" tests!

stephen-swensen commented 5 years ago

@0x53A hi - looking at this more closely in earnest now as part of https://github.com/SwensenSoftware/unquote/pull/146 ...

This is failing because of the new expression type WithValue introduced by https://github.com/fsharp/fslang-design/blob/master/FSharp-4.0/AutoQuotationDesignAndSpec.md ... I'll work on supporting this, but in the mean time, I think you can just change your use of the ReflectedDefinition attribute from ReflectedDefinition(true) to ReflectedDefinition(false).

stephen-swensen commented 5 years ago

https://github.com/SwensenSoftware/unquote/pull/146/commits/cd43d38f8cf50545c18e81e4dbd344f6ffd77ada