D-Programming-Language/dmd — pull request #3518 by jpf91 (2014-05-01 18:58:55+00:00)
Title: Add enhanced unittest support

As discussed in the newsgroup this reboots https://github.com/D-Programming-Language/druntime/pull/308
and https://github.com/D-Programming-Language/dmd/pull/1131

Ping @andralex
This provides enough to run unittests separately and in different threads, no support for naming tests yet. @andralex what's the preferred syntax for that?

### Detailed description ###

The new information is available from the ```unitTests``` member of every ModuleInfo.
```unitTests``` is an array of ```__UnitTest``` structs. The ```__UnitTest``` struct provides the unittest function, location, etc as property functions.

Internally, ```__UnitTest``` only stores a version number and an ```_impl``` pointer. ```_impl``` points to an instance of ```__UnitTest_V1``` / ```__UnitTest_V2``` / etc depending on the version number stored in ```__UnitTest```.

#### Example ####
```d
void main()
{
import std.stdio;
foreach(info; ModuleInfo)
{
foreach(test; info.unitTests)
{
writefln("ver=%s file=%s:%s disabled=%s func=%s", test.ver, test.file, test.line, test.disabled, test.func);
test.func()();
}
}
}
```

### Potential problems ###
This places the unittest array before the module name in the module info. I'd like some feedback from DMD devs if this is an issue. If we place it after the name we have a problem with alignment:
The module name may have an arbitrary length and ```dtsize_t``` doesn't align the output. No problem on X86, no-go for older ARMs. So if someone tells me how to get ```dtsize_t``` to align the output I could also add this after the module name.

### Available information ###
The following information is emitted for every unittest:
* ```void function() func```. Call it, pass it to another thread, disassemble, ...
* ```string file```: file name. nice for IDE cause not all unittests always belong to the module (for example, importing ```std.stdio``` imports two unittests from ```std.format```)
* ```uint line```: line of test declaration. For IDE
* ```bool disabled``` true if test is marked ```@disable```. (This can be removed if it's controversial)

### Adding more information to unittests ###

To add further information to unittests in the future, do this:
* Declare ```__UnitTest_V2``` with the new fiels
* Add support for version 2 to ```__UnitTest```
* Set the version to version 2 in DMD, glue.c
(search for ```// version=1```)
* Update identifier in idgen.c (```UnitTestImpl``` => ```__UnitTest_V2```)
* Update ```UnitTestDeclaration::toUnitTestInfo``` to initialize the
new fields.