Difference between revisions of "DIP83"
Line 38: | Line 38: | ||
If DMD is called with this flag it will then rewrite the AST to replace calls to | If DMD is called with this flag it will then rewrite the AST to replace calls to | ||
− | + | <syntaxhighlight lang="d"> | |
assert(lhs == rhs) | assert(lhs == rhs) | ||
− | + | </syntaxhighlight> | |
with | with | ||
− | + | <syntaxhighlight lang="d"> | |
assertBinOp(A_FILE, A_LINE, A_COLUMN, "==")(lhs == rhs, lhs, rhs) | assertBinOp(A_FILE, A_LINE, A_COLUMN, "==")(lhs == rhs, lhs, rhs) | ||
− | + | </syntaxhighlight> | |
where | where | ||
− | + | <syntaxhighlight lang="d"> | |
assertBinOp(string file, uint line, uint column, string op)(E, L, R)(lazy E expression, lazy L lhs, lazy R rhs) | assertBinOp(string file, uint line, uint column, string op)(E, L, R)(lazy E expression, lazy L lhs, lazy R rhs) | ||
− | + | </syntaxhighlight> | |
+ | |||
and similarly for unary expressions. | and similarly for unary expressions. | ||
Line 65: | Line 66: | ||
For example a failing | For example a failing | ||
− | + | <syntaxhighlight lang="d"> | |
assert([1,2,3] == [1,2,4]); | assert([1,2,3] == [1,2,4]); | ||
− | + | </syntaxhighlight> | |
could fancy-print | could fancy-print | ||
− | + | <syntaxhighlight lang="d"> | |
([1,2,3][2] being 3) != ([1,2,4][2] being 4) | ([1,2,3][2] being 3) != ([1,2,4][2] being 4) | ||
− | + | </syntaxhighlight> | |
or for aggregates a failing | or for aggregates a failing | ||
− | + | <syntaxhighlight lang="d"> | |
struct A { int x, y; } | struct A { int x, y; } | ||
auto a = A(1,2); | auto a = A(1,2); | ||
auto b = A(1,3); | auto b = A(1,3); | ||
assert(a == b); | assert(a == b); | ||
− | + | <syntaxhighlight> | |
could fancy-print | could fancy-print | ||
− | + | <syntaxhighlight lang="d"> | |
(a.y being 2) != (b.y being 3) | (a.y being 2) != (b.y being 3) | ||
− | + | <syntaxhighlight> | |
− | |||
− | |||
− | + | Parts of the solution list at | |
https://issues.dlang.org/show_bug.cgi?id=5547#c3 | https://issues.dlang.org/show_bug.cgi?id=5547#c3 | ||
− | + | including rewriting/expansion of '''AssertExpr''' could probably reused. | |
== Impact == | == Impact == |
Revision as of 17:11, 1 October 2015
Title: | Configurable Assert Diagnostics |
---|---|
DIP: | 83 |
Version: | 1 |
Status: | Draft |
Created: | 2015-10-01 |
Last Modified: | 2015-10-1 |
Author: | Per Nordlöw |
Links: |
Abstract
Allow for assert's to do pretty printing of its failing expression. Printing is configurable via specific sets of (template) function overloads.
Rationale
Typically added/modified by the developer by changing the flags to calls to rdmd/dub/scons etc upon failure with `-unittest` for a specific failing module. This will be more convenient than explicitly adding the prints of `lhs` and `rhs` in the failing unittest.
Description
This DIP proposes to add library-level-configurable diagnostics to failing calls to assert(expr) typically called from within unittest-blocks.
This diagnostics is activated only when DMD is called with a specific command line flag, say `-unittest=verbose`.
If DMD is called with this flag it will then rewrite the AST to replace calls to
assert(lhs == rhs)
with
assertBinOp(A_FILE, A_LINE, A_COLUMN, "==")(lhs == rhs, lhs, rhs)
where
assertBinOp(string file, uint line, uint column, string op)(E, L, R)(lazy E expression, lazy L lhs, lazy R rhs)
and similarly for unary expressions.
The default implementation of `assertBinOp` (preferrably defined somewhere in `druntime`) would be some standard D code that mimics the current behaviour of `assert(expression)` by throwing an `AssertExpression` if `cast(bool)expression` is `false` (dont know about the behaviour of nothrow/@nogc discussed above though). The Phobos-developer can then do what he likes with the information he needs in the extra arguments in specific templated overloads of `assertBinOp`.
This specific behaviour could be extendable by adding (typically templated) overloads of `assertBinOp` for specific sets of types (concepts).
Then we could get the extendability we want in testing-frameworks such as this without adding a new `assert`-overload-set and without sacrifycing default memory usage in DMD/Phobos unittests.
Further with this solution we could add cool diagnostics behaviour in `assertBinOp` for failing array/range comparisons aswell in a format. This diagnostics could even have different pretty printing backends such as HTML.
For example a failing
assert([1,2,3] == [1,2,4]);
could fancy-print
([1,2,3][2] being 3) != ([1,2,4][2] being 4)
or for aggregates a failing
<syntaxhighlight lang="d"> struct A { int x, y; } auto a = A(1,2); auto b = A(1,3); assert(a == b); <syntaxhighlight>
could fancy-print
<syntaxhighlight lang="d"> (a.y being 2) != (b.y being 3) <syntaxhighlight>
Parts of the solution list at
https://issues.dlang.org/show_bug.cgi?id=5547#c3
including rewriting/expansion of AssertExpr could probably reused.
Impact
Copyright
This document has been placed in the Public Domain.