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

Improve evaluation steps with lambdas #163

Closed cmeeren closed 6 months ago

cmeeren commented 1 year ago

(Not sure how general this problem is.)

Consider this code:

let width = 2

test
    <@
        "a test".Split(" ")
        |> Array.forall (fun s -> s.Length <= width)
    @>

This is displayed as:

"a test".Split(" ", None) |> Array.forall (fun s -> s.Length <= width)
[|"a"; "test"|] |> Array.forall (fun s -> s.Length <= width)
false

It would be nice to have the value of width rendered at some point.

stephen-swensen commented 6 months ago

Hi @cmeeren - this is indeed a general problem: we don't reduce lambda expressions (because in general we don't have insight into how they may be evaluated, such as this example where the lambda is evaluated multiple times by Array.forall with dynamic s; granted width is static here but it is perhaps too complex to venture that kind of analysis).

There are ways you could refactor your test to gain greater insight, for example:

    let width = 2
    let testCases =
        "a test".Split(" ")
        |> Array.map (fun s -> <@ s.Length <= width @>)

    for testCase in testCases do
        test testCase

produces the following output:

s.Length <= width
"test".Length <= 2
4 <= 2
false