DIP83
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 D compilation flags (DFLAGS) 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 the left-hand-side expression lhs and righ-hand-side expression rhs of assert expression 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 assert expression (AssertExpr in dmd source) such as
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 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).
In this way D would get the extendability we want in testing-frameworks such as std.experimental.unittests without adding a new assert-overload-set and without sacrifycing default memory usage in DMD/Phobos unittests.
Further, this solution enables the possibility to provide fancy diagnostics behaviour in assertBinOp for failing array/range or aggregate (struct or class) comparisons. This diagnostics could also have different pretty printing backends such as HTML.
For example a failing
assert([1,2,3] == [1,2,4]);
could pretty-print
([1,2,3][2] being 3) != ([1,2,4][2] being 4)
or for aggregates a failing
struct A { int x, y; }
auto a = A(1,2);
auto b = A(1,3);
assert(a == b);
could pretty-print
(a.y being 2) != (b.y being 3)
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.