1 /**
2  * Tests/Examples of Pijamas
3  *
4  * Authors: Pedro Tacla Yamada, Luis Panadero Guardeño
5  * License: Licensed under the MIT license. See LICENSE for more information.
6  */
7 module pijamas_spec_nogc;
8 
9 import std.exception;
10 
11 import pijamas;
12 import pijamas.exception : AssertException;
13 
14 version (MirNoGCException) {
15 
16   @("@nogc Should Assertion.exist")
17   @nogc
18   @trusted unittest {
19     //  it("existence of string",
20     {
21       // String
22       string str;
23       str.should.not.exist;
24 
25       string str2 = null;
26       str2.should.not.exist;
27 
28       string str3 = "hello";
29       str3.should.exist;
30 
31       should(() { string str; str.should.not.exist; }).not.Throw!AssertException;
32 
33       should(() { string str = null; str.should.exist; }).Throw!AssertException;
34     }
35 
36     //  it("With not nullable, must do nothing
37     {
38       int i = 10;
39       i.should.exist;
40       i.should.not.exist;
41 
42       struct S {
43         int x;
44       }
45 
46       should(() { S s; s.should.exist; }).not.Throw!AssertException;
47 
48       should(() { S s; s.should.not.exist; }).not.Throw!AssertException;
49     }
50 
51     //  it("Pointer not being a null pointer"
52     {
53       // Ptr
54       int* ptr = null;
55       ptr.should.not.exist;
56 
57       should(() { int* ptr = null; ptr.should.exist; }).Throw!AssertException;
58 
59       int value;
60       ptr = &value;
61       ptr.should.exist;
62     }
63 
64     //  it("Class reference"
65     {
66       // Class
67       class C {
68         int x;
69         this() @nogc {
70         }
71       }
72 
73       C c;
74       c.should.not.exist;
75       should(() { C c; c.should.exist; }).Throw!AssertException;
76 
77       import std.experimental.allocator;
78       import std.experimental.allocator.mallocator : Mallocator;
79 
80       c = Mallocator.instance.make!C();
81       c.should.exist;
82     }
83   }
84 
85   @("@nogc Should Assertion.True")
86   @nogc
87   @trusted unittest {
88     // it("returns and asserts for true",
89     {
90       true.should.be.True;
91       (1 == 1).should.be.True;
92     }
93 
94     // it("throws for false",
95     {
96       (1 != 1).should.not.be.True;
97       should(() { false.should.be.True; }).Throw!AssertException;
98     }
99   }
100 
101   @("@nogc Should Assertion.False")
102   @nogc
103   @trusted unittest {
104     // it("returns and asserts for false",
105     {
106       false.should.be.False;
107       (1 != 1).should.be.False;
108     }
109 
110     // it("throws for true",
111     {
112       true.should.not.be.False;
113       should(() { (1 == 1).should.be.False; }).Throw!AssertException;
114     }
115   }
116 
117   @nogc
118   @("@nogc Should Assertion.equal")
119   @trusted unittest {
120     //  it("asserts whether two values are equal",
121     {
122       10.should.be.equal(10);
123       10.expect.to.be.equal(10);
124       10.should.not.be.equal(5);
125       10.should.not;
126       should(() { 10.should.be.equal(2); }).Throw!AssertException;
127     }
128 
129     //  it("works for arrays",
130     {
131       int[4] a = [1, 2, 3, 4];
132       int[4] b = [1, 2, 3, 4];
133 
134       a.should.be.equal(b);
135 
136       byte[3] a2 = [0, 2, 1];
137       a2.should.not.be.equal(b);
138 
139       should(() {
140         int[4] u = [1, 2, 3, 4];
141         int[4] v = [6, 2, 3, 4];
142         u.should.be.equal(v);
143       }).Throw!AssertException;
144     }
145 
146     //  it("works for structs",
147     {
148       struct ExampleS {
149         bool a = false;
150         string f = "something";
151       }
152 
153       auto e = ExampleS(true, "here");
154       e.should.be.equal(ExampleS(true, "here"));
155       e.should.be.not.equal(ExampleS(true, "asdf"));
156 
157       should(() {
158         auto e = ExampleS(true, "here");
159         e.should.be.equal(ExampleS(true, "asdf"));
160       }).Throw!AssertException;
161     }
162 
163     /+
164     //  it("works for classes",
165     {
166       class ExampleC {
167         int x;
168         this(int x) @nogc {
169           this.x = x;
170         }
171 
172         ~this() @nogc {
173         }
174 
175         override bool opEquals(Object o) const @nogc // @trusted
176         {
177           if (ExampleC rhs = cast(ExampleC) o) {
178             return this.x == rhs.x;
179           }
180           return false;
181         }
182       }
183 
184       class OtherClass {
185         int x;
186         this(int x) @nogc {
187           this.x = x;
188         }
189         ~this() @nogc {
190         }
191       }
192 
193       import std.experimental.allocator;
194       import std.experimental.allocator.mallocator : Mallocator;
195       auto m = Mallocator.instance;
196 
197       auto c = m.make!ExampleC(33);
198       auto another = m.make!ExampleC(33);
199       auto different = m.make!ExampleC(33);
200 
201       scope(exit) {
202         // WTF? Why I get that dispose it's nogc ?
203         m.dispose(c);
204         m.dispose(another);
205         m.dispose(different);
206       }
207 
208       // opEquals can't be @nogc ?
209       // c.should.be.equal(another);
210       e.should.be.not.equal(new ExampleC(1));
211       assertThrown!AssertException(e.should.be.equal(new ExampleC(1)));
212 
213       e.should.be.not.equal(new OtherClass(33));
214       assertThrown!AssertException(e.should.be.equal(new OtherClass(33)));
215     }
216     +/
217   }
218 
219   @("@nogc Should Assertion.approxEqual")
220   @nogc
221   @trusted unittest {
222     // it("asserts that the identical value are identical")
223     {
224       float f = 0.01;
225       f.should.be.approxEqual(f);
226       f.should.be.close(f);
227 
228       double d = 0.01;
229       d.should.be.approxEqual(d);
230 
231       real r = 0.01;
232       r.should.be.approxEqual(r);
233     }
234 
235     // it("handles comparing diferent float types")
236     {
237       float f = 0.01;
238       double d = 0.01;
239       real r = 0.01;
240       f.should.be.approxEqual(d);
241       f.should.be.approxEqual(r);
242 
243       d.should.be.approxEqual(f);
244       d.should.be.approxEqual(r);
245 
246       r.should.be.approxEqual(f);
247       r.should.be.approxEqual(d);
248     }
249 
250     // it("asserts that two nearly identical float values are approximated equal")
251     {
252       float one = 1_000_000_000.0;
253       one.should.be.close(999_999_999.0);
254 
255       double d = 0.1;
256       double d2 = d + 1e-10;
257       d.should.not.be.equal(d2);
258       d.should.be.approxEqual(d2);
259 
260       // and("when increase the difference, it must not be approximated equals")
261       d2 += 1e-5;
262       d.should.not.be.equal(d2);
263       d.should.not.be.approxEqual(d2);
264 
265       should(() {
266         double d = 0.1;
267         double d2 = d + 1e-10 + 1e-5;
268         d.should.be.approxEqual(d2);
269       }).Throw!AssertException;
270 
271       // and("Different default limits for different floating point types")
272       float oneFloat = 1.0f;
273       double oneDouble = 1.0;
274       oneFloat.should.be.close(0.999_99f);
275       oneDouble.should.not.be.close(0.999_99);
276     }
277   }
278 
279   /+
280   std.regex requires GC
281   import std.regex : regex, ctRegex;
282   auto r = regex(`[a-z]+`);
283   auto ctr = ctRegex!`[a-z0-9]+`;
284 
285   @("@nogc Should Assertion.match")
286   @nogc
287   @trusted unittest {
288     // it("returns whether a string type matches a Regex",
289     {
290       import std.regex : regex;
291 
292       string str = "Something weird";
293       str.should.match(r);
294       should(() {
295         "123".should.match(r);
296       }).Throw!AssertException;
297     }
298 
299     // it("returns whether a string type matches a StaticRegex",
300     {
301       import std.regex : ctRegex;
302 
303       string str = "something 2 weird";
304       str.should.match(ctr);
305       should(() {
306         "$^".should.match(ctr);
307       }).Throw!AssertException;
308     }
309 
310     // it("returns whether a string type matches a string regex",
311     {
312       string str = "1234numbers";
313       str.should.match(`[0-9]+[a-z]+`);
314       str.should.not.match(`^[a-z]+`);
315       should(() {
316        "1234numbers".should.match(`^[a-z]+`);
317       }).Throw!AssertException;
318     }
319   }
320   +/
321 
322   @("@nogc Should Assertion.include")
323   @nogc
324   @trusted unittest {
325     // it("asserts for arrays containing elements",
326     {
327       int[6] a = [1, 2, 3, 4, 5, 6];
328       a.should.include(4);
329       a.should.not.include(7);
330       should(() {
331         int[6] a = [1, 2, 3, 4, 5, 6];
332         a.should.include(7);
333       }).Throw!AssertException;
334     }
335 
336     /+
337     // it("asserts for associative arrays containing values",
338     {
339       int[string] aa = ["something": 2, "else": 3];
340       aa.should.have.value(2);
341       aa.should.not.have.value(4);
342       assertThrown!AssertException(aa.should.have.value(42));
343     }
344     +/
345 
346     // it("asserts for strings containing characters",
347     {
348       string str = "asdf1";
349       str.should.include('a');
350       //str.should.include("sd");
351       str.should.not.include(2);
352       str.should.not.include('u');
353       should(() {
354         "asdf1".should.include('z');
355       }).Throw!AssertException;
356     }
357   }
358 
359   @("@nogc Should Assertion.length")
360   @nogc
361   @trusted unittest {
362     // it("asserts for length equality for strings",
363     {
364       auto str = "1234567";
365       str.should.have.length(7);
366       should(() {
367         "1234567".should.have.length(17);
368       }).Throw!AssertException;
369     }
370 
371     // it("asserts for length equality for arrays",
372     {
373       int[6] a = [1, 2, 3, 4, 5, 6];
374       a.should.have.length(6);
375       should(() {
376         int[6] a = [1, 2, 3, 4, 5, 6];
377         a.should.have.length(17);
378       }).Throw!AssertException;
379     }
380 
381     /+
382     // it("asserts for length equality for associative arrays",
383     {
384       string[string] aa = [
385         "something": "here", "what": "is", "this": "stuff", "we're": "doing"
386       ];
387       aa.should.have.length(4);
388       assertThrown!AssertException(aa.should.have.length(24));
389     }
390     +/
391   }
392 
393   @("@nogc Should Assertion.empty")
394   @nogc
395   @trusted unittest {
396     // it("asserts that a string is empty"
397     {
398       auto str = "1234567";
399       str.should.not.be.empty;
400       "".should.be.empty;
401       should(() {
402         "1234567".should.be.empty;
403       }).Throw!AssertException;
404     }
405 
406     // it("asserts that an array is empty"
407     {
408       int[6] a = [1, 2, 3, 4, 5, 6];
409       a.should.not.be.empty;
410       should(() {
411         int[6] a = [1, 2, 3, 4, 5, 6];
412         a.should.be.empty;
413       }).Throw!AssertException;
414 
415       int[10] emptyArr;
416       emptyArr.should.not.be.empty;
417       // A static array contains N values of T.init, so never can be empty
418     }
419 
420     /+
421     // it("asserts that an associative array is empty",
422     {
423       string[string] aa = [
424         "something": "here", "what": "is", "this": "stuff", "we're": "doing"
425       ];
426       aa.should.not.be.empty;
427       assertThrown!AssertException(aa.should.be.empty);
428       int[string] emptyAa;
429       emptyAa.should.be.empty;
430     }
431     +/
432   }
433 
434   @("@nogc Should Assertion.biggerThan")
435   @nogc
436   @trusted unittest {
437     //it("asserts whether a value is bigger than other",
438     {
439       auto a1 = true;
440       a1.should.be.biggerThan(0);
441       a1.should.be.biggerThan(false);
442 
443       auto a2 = "aab";
444       a2.should.be.biggerThan("aaa");
445       a2.should.not.be.biggerThan("zz");
446       should(() {
447         "aab".should.be.biggerThan("zz");
448       }).Throw!AssertException;
449 
450       10.should.be.biggerOrEqualThan(10);
451       50.should.be.biggerOrEqualThan(10);
452     }
453   }
454 
455   @("@nogc Should Assertion.smallerThan")
456   @nogc
457   @trusted unittest {
458     // it("asserts whether a value is smaller than other",
459     {
460       auto a1 = false;
461       a1.should.be.smallerThan(1);
462       a1.should.be.smallerThan(true);
463 
464       auto a2 = 1000;
465       a2.should.be.smallerThan(2000);
466       a2.should.be.not.smallerThan(99);
467       should(() {
468         1000.should.be.smallerThan(99);
469       }).Throw!AssertException;
470 
471       10.should.be.smallerOrEqualThan(10);
472       10.should.be.smallerOrEqualThan(50);
473     }
474   }
475 
476   /+
477   std.algorithm.sorting : isSorted isn't nogc compatible
478   @("@nogc Should Assertion.sorted")
479   @nogc
480   @trusted unittest {
481     // it("asserts whether a range is sorted",
482     {
483       int[4] unsorted = [4, 3, 2, 1];
484       unsorted.should.not.be.sorted;
485 
486       should(() {
487         int[4] unsorted = [4, 3, 2, 1];
488         unsorted.should.be.sorted;
489       }).Throw!AssertException;
490 
491       int[5] sortedAr = [1, 2, 3, 4, 8];
492       sortedAr.should.be.sorted;
493       should(() {
494         int[5] sortedAr = [1, 2, 3, 4, 8];
495         sortedAr.should.not.be.sorted;
496       }).Throw!AssertException;
497     }
498   }
499   +/
500 }