1 module unit_threaded.ut.property;
2 
3 import unit_threaded.property;
4 import unit_threaded.asserts;
5 
6 @("Verify anti-identity property for int[] fails")
7 @safe unittest {
8     import unit_threaded.should;
9     int numCalls;
10     bool antiIdentity(int[] a) {
11         ++numCalls;
12         return a != a;
13     }
14 
15     check!antiIdentity.shouldThrow!UnitTestException;
16     // gets called twice due to shrinking
17     numCalls.shouldEqual(2);
18 }
19 
20 @("Verify property that sometimes succeeds")
21 @safe unittest {
22     // 2^100 is ~1.26E30, so the chances that no even length array is generated
23     // is small enough to disconsider even if it were truly random
24     // since Gen!int[] is front-loaded, it'll fail deterministically
25     assertExceptionMsg(check!((int[] a) => a.length % 2 == 1)(42),
26                        "    tests/unit_threaded/ut/property.d:123 - Property failed. Seed: 42. Input: []");
27 }
28 
29 
30 @("shrink int when already shrunk")
31 @safe pure unittest {
32     assertEqual(0.shrink!(a => a != 0), 0);
33 }
34 
35 
36 @("shrink int when not already shrunk going up")
37 @safe pure unittest {
38     assertEqual(0.shrink!(a => a > 3), 3);
39 }
40 
41 @("shrink int when not already shrunk going down")
42 @safe pure unittest {
43     assertEqual(10.shrink!(a => a < -3), -3);
44 }
45 
46 @("shrink int.max")
47 @safe pure unittest {
48     assertEqual(int.max.shrink!(a => a == 0), 1);
49     assertEqual(int.min.shrink!(a => a == 0), -1);
50     assertEqual(int.max.shrink!(a => a < 3), 3);
51 }
52 
53 @("shrink unsigneds")
54 @safe pure unittest {
55     import std.meta;
56     foreach(T; AliasSeq!(ubyte, ushort, uint, ulong)) {
57         T value = 3;
58         assertEqual(value.shrink!(a => a == 0), 1);
59     }
60 }
61 
62 @("shrink empty int array")
63 @safe pure unittest {
64     int[] value;
65     assertEqual(value.shrink!(a => a != []), value);
66 }
67 
68 @("shrink int array")
69 @safe pure unittest {
70     assertEqual([1, 2, 3].shrink!(a => a == []), [1]);
71 }
72 
73 @("shrink string")
74 @safe pure unittest {
75     import std.algorithm: canFind;
76     assertEqual("abcdef".shrink!(a => !a.canFind("e")), "e");
77 }
78 
79 @("shrink one item with check")
80 unittest {
81     assertEqual("ǭĶƶØľĶĄÔ0".shrink!((s) => s.length < 3 || s[2] == 'e'), "ǭ");
82 }
83 
84 @("shrink one item with check")
85 unittest {
86     assertExceptionMsg(check!((int i) => i < 3)(33),
87                        "    tests/unit_threaded/ut/property.d:123 - Property failed. Seed: 33. Input: 3");
88 }
89 
90 @("string[]")
91 unittest {
92     bool identity(string[] a) pure {
93         return a == a;
94     }
95     check!identity;
96 }
97 
98 @("property test on user defined struct")
99 unittest {
100     struct Foo {
101         int i;
102         short s;
103     }
104 
105     bool identity(Foo f) pure {
106         return f == f;
107     }
108 
109     check!identity;
110 }
111 
112 @("issue 93 uint")
113 unittest {
114     import unit_threaded.should;
115     check!((uint i) => i != i)(77).shouldThrowWithMessage("Property failed. Seed: 77. Input: 0");
116 }
117 
118 @("issue 93 array")
119 unittest {
120     import unit_threaded.should;
121     check!((int[] i) => i != i)(11).shouldThrowWithMessage("Property failed. Seed: 11. Input: []");
122 }
123 
124 @("check function that throws is the same as check function that returns false")
125 @safe unittest {
126     import unit_threaded.should;
127     bool funcThrows(uint) {
128         throw new Exception("Fail!");
129     }
130     check!funcThrows(42).shouldThrowWithMessage("Property threw. Seed: 42. Input: 0. Message: Fail!");
131 }