1 /** 2 UDAs for decorating tests. 3 */ 4 module unit_threaded.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 68 69 /** 70 Used as a UDA for built-in unittests to enable value-parametrized tests. 71 Example: 72 ------- 73 @Values(1, 2, 3) unittest { assert(getValue!int % 2 == 0); } 74 ------- 75 The example above results in unit_threaded running the unit tests 3 times, 76 once for each value declared. 77 78 See `getValue`. 79 */ 80 auto Values(T)(T[] values...) { 81 return ValuesImpl!T(values.dup); 82 } 83 84 auto Values(R)(R values) if(from!"std.range.primitives".isInputRange!R) { 85 import std.range.primitives: ElementType; 86 import std.array: array; 87 return ValuesImpl!(ElementType!R)(values.array); 88 } 89 90 91 struct ValuesImpl(T) { 92 T[] values; 93 } 94 95 /** 96 Retrieves the current test value of type T in a built-in unittest. 97 See `Values`. 98 */ 99 T getValue(T, int index = 0)() { 100 return ValueHolder!T.values[index]; 101 } 102 103 package struct ValueHolder(T) { 104 static T[10] values; 105 } 106 107 108 enum Setup; 109 enum Shutdown; 110 111 struct Flaky { 112 /// the number of times to run the test 113 enum defaultRetries = 10; 114 int retries = defaultRetries; 115 }