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 /// The suite fails unless the test throws T
22 struct ShouldFailWith(T: Throwable) {
23     alias Type = T;
24     string reason;
25 }
26 
27 /// Associate a name with a unittest block.
28 struct Name {
29     string value;
30 }
31 
32 /// Associates one or more tags with the test
33 struct Tags {
34     this(string[] values...) { this.values = values;}
35     this(string[] values) { this.values =  values; }
36     this(string value)    { this.values = [value]; }
37     string[] values;
38 }
39 
40 /** Automatically assign @Tags for each parameterized test
41  e.g.
42 ---------------
43 @Values("foo", "bar") @AutoTags unittest { ... }
44 // there are now two unit tests, one for "foo" with tag "foo"
45 // and one for "bar" with tag "bar"
46 ---------------
47  */
48 enum AutoTags;
49 
50 /** Attachs these types to the a parametrized unit test.
51     The attached template function will be instantiated with
52     each type listed, e.g.
53 
54     ----------------
55     @Types!(int, byte) void testInit(T)() { T.init.shouldEqual(0); }
56     ----------------
57 
58     These would mean two testInit test runs.
59 
60     Normally this would be a template but I don't know how to write
61  *  the UDA code to filter a template out
62  */
63 struct Types(T...) {}
64 
65 
66 /**
67  Used as a UDA for built-in unittests to enable value-parametrized tests.
68  Example:
69  -------
70  @Values(1, 2, 3) unittest { assert(getValue!int % 2 == 0); }
71  -------
72  The example above results in unit_threaded running the unit tests 3 times,
73  once for each value declared.
74 
75  See `getValue`.
76  */
77 auto Values(T)(T[] values...) {
78     return ValuesImpl!T(values.dup);
79 }
80 
81 auto Values(R)(R values) if(isInputRange!R) {
82     import std.array;
83     return ValuesImpl!(ElementType!R)(values.array);
84 }
85 
86 
87 struct ValuesImpl(T) {
88     T[] values;
89 }
90 
91 /**
92  Retrieves the current test value of type T in a built-in unittest.
93  See `Values`.
94  */
95 T getValue(T, int index = 0)() {
96     return ValueHolder!T.values[index];
97 }
98 
99 package struct ValueHolder(T) {
100     static T[10] values;
101 }
102 
103 
104 enum Setup;
105 enum Shutdown;