Unit tests in D

bearophile bearophileHUGS at lycos.com
Wed May 5 16:02:03 PDT 2010


Walter Bright>I don't see that in the example given.<

I can try with one real example from my dlibs1. This template is the third I use with foreach to create the fake static foreach, this accepts a step (stride) value too.

But such step can't be zero, so I add a static assert inside it to make sure you don't try to instantiate it with a step = 0.


template Range(int start, int stop, int step) {
    static assert(step != 0, "Range: step must be != 0");

    static if (step > 0) {
        static if (stop <= start)
            alias Tuple!() Range;
        else
            alias Tuple!(Range!(start, stop-step, step), stop-step) Range;
    } else {
        static if (stop >= start)
            alias Tuple!() Range;
        else
            alias Tuple!(Range!(start, stop-step, step), stop-step) Range;
    }
}


In D2 I can use a template constraint instead of a static assert here (this is sometimes bad, because you lose the error text message given by the static assert, that in complex situations can be useful):

template Range(int start, int stop, int step) if (step != 0) {


Now that Range needs unittests, things like this that test that Range gives the right output:

unittest { // Tests of Range!()
    int[] a;
    foreach (n; Range!(0, 10, 2))
        a ~= n;
    assert(a == [0, 2, 4, 6, 8]);
}


But the "specs" of the Range template say that Range must not work if step is zero (this means that the unittest has to fail if Range compiles when the given step is zero). So I have to test this too. I can do that with one more unittest (D1 code):

    static assert(!is(typeof( Range!(15, 3, 0) )));

In D2 I can use the __traits:

    static assert(!__traits(compiles, Range!(15, 3, 0) ));

Hope this helps.

Bye,
bearophile


More information about the Digitalmars-d mailing list