1 module unit_threaded.attrs;
2 
3 import std.range;
4 
5 enum UnitTest; //opt-in to registration
6 enum DontTest; //opt-out of registration
7 enum Serial; //run tests in the module in one thread / serially
8 
9 alias SingleThreaded = Serial;
10 
11 ///Hide test. Not run by default but can be run.
12 struct HiddenTest {
13     string reason;
14 }
15 
16 /// The suite fails if the test passes.
17 struct ShouldFail {
18     string reason;
19 }
20 
21 /// Associate a name with a unittest block.
22 struct Name {
23     string value;
24 }
25 
26 /// Associates one or more tags with the test
27 struct Tags {
28     this(string[] values...) { this.values = values;}
29     this(string[] values) { this.values =  values; }
30     this(string value)    { this.values = [value]; }
31     string[] values;
32 }
33 
34 /** Automatically assign @Tags for each parameterized test
35  e.g.
36 ---------------
37 @Values("foo", "bar) @AutoTags unittest { ... }
38 // there are now two unit tests, one for "foo" with tag "foo"
39 // and one for "bar" with tag "bar"
40 ---------------
41  */
42 enum AutoTags;
43 
44 /** Attachs these types to the a parametrized unit test.
45     The attached template function will be instantiated with
46     each type listed, e.g.
47 
48     ----------------
49     @Types!(int, byte) void testInit(T)() { T.init.shouldEqual(0); }
50     ----------------
51 
52     These would mean two testInit test runs.
53 
54     Normally this would be a template but I don't know how to write
55  *  the UDA code to filter a template out
56  */
57 struct Types(T...) {}
58 
59 
60 /**
61  Used as a UDA for built-in unittests to enable value-parametrized tests.
62  Example:
63  -------
64  @Values(1, 2, 3) unittest { assert(getValue!int % 2 == 0); }
65  -------
66  The example above results in unit_threaded running the unit tests 3 times,
67  once for each value declared.
68 
69  See `getValue`.
70  */
71 auto Values(T)(T[] values...) {
72     return ValuesImpl!T(values.dup);
73 }
74 
75 auto Values(R)(R values) if(isInputRange!R) {
76     import std.array;
77     return ValuesImpl!(ElementType!R)(values.array);
78 }
79 
80 
81 struct ValuesImpl(T) {
82     T[] values;
83 }
84 
85 /**
86  Retrieves the current test value of type T in a built-in unittest.
87  See `Values`.
88  */
89 T getValue(T, int index = 0)() {
90     return ValueHolder!T.values[index];
91 }
92 
93 package struct ValueHolder(T) {
94     static T[10] values;
95 }