Difference between revisions of "DIP83"

From D Wiki
Jump to: navigation, search
Line 29: Line 29:
 
== Rationale ==
 
== 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.
+
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 ==
 
== Description ==
 +
 
This DIP proposes to add library-level-configurable diagnostics to failing calls to '''assert(expr)''' typically called from within '''unittest'''-blocks.
 
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`.
+
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  
 
If DMD is called with this flag it will then rewrite the AST to replace calls to  

Revision as of 17:13, 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 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 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.