www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is it a bug in unittest ?

reply angel <andrey.gelman gmail.com> writes:
If one creates a unittest block in a templated class (or struct), 
the unittest block will be multiplied per class specialization, 
which might turn out to be quite large number.

E.g.
  struct A(T) {
      ...
      unittest {
          ...
      }
  }

  ...

  auto a = A!int;
  auto b = A!int;
  auto c = A!double;

The unittest block will be instantiated twice (per A!int and 
A!double).
But in some (many ?) cases unittest doesn't even exercise the 
generics, merely using some particular type.

What is it, a bug ?
Sep 01 2016
next sibling parent Lodovico Giaretta <lodovico giaretart.net> writes:
On Thursday, 1 September 2016 at 18:11:55 UTC, angel wrote:
 If one creates a unittest block in a templated class (or 
 struct), the unittest block will be multiplied per class 
 specialization, which might turn out to be quite large number.

 E.g.
  struct A(T) {
      ...
      unittest {
          ...
      }
  }

  ...

  auto a = A!int;
  auto b = A!int;
  auto c = A!double;

 The unittest block will be instantiated twice (per A!int and 
 A!double).
 But in some (many ?) cases unittest doesn't even exercise the 
 generics, merely using some particular type.

 What is it, a bug ?
I think this is inteded behaviour. If the unittest is not dependent on the current instantiation, you can move it outside the template. By the way, it is common practice to put unittests after, and not inside, the tested struct/class. That is: =========== struct A(T) { unittest { A a; // uses current instantiation; repeated for every instantiation } } unittest { A!int b; // tests specific instantiations A!double c; // not repeated } ===========
Sep 01 2016
prev sibling next sibling parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Thu, Sep 01, 2016 at 06:11:55PM +0000, angel via Digitalmars-d wrote:
 If one creates a unittest block in a templated class (or struct), the
 unittest block will be multiplied per class specialization, which
 might turn out to be quite large number.
 
 E.g.
  struct A(T) {
      ...
      unittest {
          ...
      }
  }
 
  ...
 
  auto a = A!int;
  auto b = A!int;
  auto c = A!double;
 
 The unittest block will be instantiated twice (per A!int and
 A!double).  But in some (many ?) cases unittest doesn't even exercise
 the generics, merely using some particular type.
 
 What is it, a bug ?
It can be construed to be a bug or a feature, depending on how you use it. :-) A unittest block inside a template is generally useful for testing things that depend on the template parameters, e.g., to ensure that A!int, A!double, A!string, etc., all satisfy certain requirements. But if the unittest block tests only specific instantiations, e.g., only A!int, then it's better to move it outside the template body, so that it's only instantiated once. In other words, unittest inside a template body is useful for testing *all* instantiations of a template; unittest outside a template body is useful for testing *specific* instantiations. Of course, moving unittests outside the template is troublesome if you're using the ddoc'd unittest feature (where the body of a unittest becomes part of a member function's documentation). In such cases you could do something like this: struct A(T) { /// ddoc body here auto myMethod(Args)(Args args) { ... } static if (T == int) /// unittest { ... // test A!int here } } // of course, make sure the unittest actually runs! version(unittest) auto A_int = A!int; T -- Doubtless it is a good thing to have an open mind, but a truly open mind should be open at both ends, like the food-pipe, with the capacity for excretion as well as absorption. -- Northrop Frye
Sep 01 2016
prev sibling parent ZombineDev <petar.p.kirov gmail.com> writes:
On Thursday, 1 September 2016 at 18:11:55 UTC, angel wrote:
 If one creates a unittest block in a templated class (or 
 struct), the unittest block will be multiplied per class 
 specialization, which might turn out to be quite large number.

 E.g.
  struct A(T) {
      ...
      unittest {
          ...
      }
  }

  ...

  auto a = A!int;
  auto b = A!int;
  auto c = A!double;

 The unittest block will be instantiated twice (per A!int and 
 A!double).
 But in some (many ?) cases unittest doesn't even exercise the 
 generics, merely using some particular type.

 What is it, a bug ?
Not a bug. Everything inside a template get copied for each template instantiation. It would strange if there were exceptions. That doesn't mean that it is an intentional feature. See http://wiki.dlang.org/DIP82.
Sep 02 2016