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