On 28/11/13 19:01, Dicebot wrote:
On Thursday, 28 November 2013 at 17:28:56 UTC, Gary Willoughby wrote:
On Thursday, 28 November 2013 at 17:22:20 UTC, Dicebot wrote:
I don't know what is the proper way to handle this but current situation is
clearly worth a bugzilla entry. It is just weird.

Maybe this is intended behaviour to handle testing AssertErrors in unit tests?
How else could you test them.

It is tricky.

The basic problem is this: if you compile something with -release -unittest, it will strip out all assert statements and contracts _in the main code_, while preserving assert statements etc. inside the unittest blocks.

Now, if you compile with -release -unittest, quite obviously you want the unittests to test the code _as compiled for release_, so the above is entirely correct behaviour. It becomes problematic when you want to start testing behaviour that should take place in non-release mode but not in release mode (or vice versa).

The _reason_ it's problematic is because inside the unittest blocks, the version(release) and version(assert) conditionals don't work as they do outside. So you can't use them inside the unittest { ... } blocks as conditionals for what tests get run.

Now, I can see the case here for version(assert) -- after all, asserts are enabled inside the unittest blocks -- but not so much for version(release). After all, if release mode is enabled, it's enabled. (Presumably the actual fact is that release-mode-style compilation is also disabled inside the unittest blocks.)

a) by not using asserts
b) by compiling unittest blocks in separate pass from main app

(a) breaks many existing tests in release, (b) does not fit well into existing
compilation model but can be worth considering

There is also (c) of course : document the fact that -unittest overrides
-release with big red words everywhere :)

I thought that it might also work to group together unittests that are conditional on version(release) or version(assert) or whatever, and put the unittest block _inside_ the version() { ... } scope. But it turns out not.

I think it may actually be a bug in whether -release implies version(release). Try out the attached code. (r)dmd -release release.d produces an executable that still reports that release mode is disabled.
import std.stdio;

void foo(string s)
{
    version(release)
    {
        writeln("Release mode is enabled for " ~ s);
    }
    else
    {
        /* NASTY!! We wind up here if we compile with
         * -unittest -release instead of just -release
         */
        writeln("Release mode is disabled for "~ s);
    }
}

void main()
{
    foo("main");
}

unittest
{
    foo("unittests");
}

Reply via email to