Print out current binding from `assert/1`/`refute/1` macros in `ex_unit`

I am not sure it deserves to be discussed in the mailing list, so I’d start here.

assert/1 and/or refute/1 macros print the following error message when they fail during a direct comparison

Error:      test/file:line
     Expected truthy, got false
     code: assert value >= min_value and value <= max_value
     stacktrace:
       test/file:line: anonymous fn/3 in Test

It would be extremely helpful to print the binding reduced to the variables used in the expression, like

...
     code: assert value >= min_value and value <= max_value
     binding: value: 1.0, min_value: 2.0, max_value: 3.0

It’s an easy change and if there is an interest, I am open to either start a discussion in the mailing list or straight provide a PR doing this.

3 Likes

Would this just be for more complex expressions? For very basic comparisons, we already get the left/right printouts:

     Assertion with >= failed
     code:  assert value >= min_value
     left:  1.0
     right: 2.0

And that works with function calls as well

     Assertion with >= failed
     code:  assert calculate(input) >= min_value
     left:  1.0
     right: 2.0

If only the bindings were shown for something like this, you would see the value of input but not the more important value of calculate(input).
One could argue you would want to store the result in a variable for more complex comparisons, but maybe instead of just bindings it could be preferable to have a step-through of evaluation? Something like

     Expected truthy, got false
     code: assert value >= min_value and value <= max_value
     eval: assert 1.0 >= 2.0 and value <= max_value
           assert false and value <= max_value
           assert false

I don’t love that, though. But I’m not sure how best to show calculated values.

1 Like

Well, I thought it would be a good addition to all of them. Yes, basic expressions do already print left and right, but even in your example it might be helpful to see input as well via bindings to quickly figure out why calculate(input) resulted in 1. Like

     Assertion with >= failed
     code:  assert calculate(input) >= min_value
     left:  1.0
     right: 2.0
     binding: input: nil, min_value: 2.0

It costs nothing but would play the role of binding inspector.

1 Like