More and more, D code is written as a component that takes a type parameters
that are ranges. Unit testing becomes inconvenient, as types must be mocked up
to call them. Using an array of data often is inadequate, because the component
may have specializations for an array, or specifies a range that is a subset of
what an array provides.
For example, here's a test range I wrote once for a unittest:
struct Adapter
{
this(ubyte[] r) { this.r = r; }
@property bool empty() { return r.length == 0; }
@property ubyte front() { return r[0]; }
void popFront() { r = r[1 .. $]; }
@property size_t length() { return r.length; }
private:
ubyte[] r;
}
I propose a std.test.ranges package, which contains templates defining each of
the range types (InputRange, BiDirectionalRange, etc.). Each accepts an argument
which is a static array of T, and then implements exactly the range interface
indicated by its name, nothing more. The range will also have asserts to
guarantee they are used correctly, i.e. front() cannot be called before empty()
returns false.
By default, those mock range templates will be @safe. They can be configured to
be @system.
Each range type will also have a corresponding testXXXRange!R(R r) function,
that tests the interface to range R to ensure that it follows the protocol
indicated by its name (there was some confusion a while back about exactly what
the protocol entailed, having a standard test function for it will help user
defined ranges be protocol correct).
Anyone interested in taking up this flag?