On 7/23/2015 2:08 PM, Dicebot wrote:
It does not protect from errors in definition

void foo (R) (Range r)
     if (isInputRange!Range)
{ r.save(); }

unittest
{
     SomeForwardRange r;
     foo(r);
}

This will compile and show 100% test coverage. Yet when user will try using it
with real input range, it will fail.

That is correct. Some care must be taken that the mock types used in the unit tests actually match what the constraint is, rather than being a superset of them.


There is quite a notable difference in clarity between error message coming from
some arcane part of function body and referring to wrong usage (or even totally
misleading because of UFCS) and simple and straightforward "Your type X does not
implement method X necessary for trait Y"

I believe they are the same. "method X does not exist for type Y".


Coverage does not work with conditional compilation:

void foo (T) ()
{
     import std.stdio;
     static if (is(T == int))
         writeln("1");
     else
         writeln("2");
}

unittest
{
     foo!int();
}

$ dmd -cov=100 -unittest -main ./sample.d

Let's look at the actual coverage report:
===============================
       |void foo (T) ()
       |{
       |    import std.stdio;
       |    static if (is(T == int))
      1|        writeln("1");
       |    else
       |        writeln("2");
       |}
       |
       |unittest
       |{
      1|    foo!int();
       |}
       |
foo.d is 100% covered
============================

I look at these all the time. It's pretty obvious that the second writeln is not being compiled in.

Now, if I make a mistake in the second writeln such that it is syntactically correct yet semantically wrong, and I ship it, and it blows up when the customer actually instantiates that line of code,

   -- where is the advantage to me? --

How am I, the developer, better off? How does "well, it looks syntactically like D code, so ship it!" pass any sort of professional quality assurance?

Reply via email to