fluentasserts.core.basetype 169/177(95%) line coverage

      
10
20
30
40
50
60
70
80
90
100
110
120
130
1470
1570
1670
170
180
190
200
210
220
230
240
250
260
2725
2825
2925
3025
310
3225
330
340
3526
360
3724
380
390
4025
410
420
430
440
450
4610
4710
4810
4910
500
5110
5220
5320
540
5510
560
570
580
590
600
610
620
6310
640
650
660
670
680
6912
7012
7112
7212
730
7412
750
7612
770
780
7912
800
810
820
830
8424
850
8612
870
880
890
900
910
9244
9344
940
9522
9622
9722
9822
9922
10022
1010
10222
10322
10441
1050
10622
1070
1080
10944
1100
11122
11211
1130
11411
1151
1160
1170
11811
1192
1200
1210
1220
12322
1240
1250
1260
1270
1280
1296
1306
1316
1326
1330
1346
1350
1360
1370
1380
1390
1402
1412
1422
1430
1440
1453
1462
1470
1480
1492
1502
1512
1520
1533
1542
1550
1560
1572
1582
1592
1600
1610
1620
1630
1642
1652
1662
1670
1680
1693
1702
1710
1720
1732
1742
1752
1760
1773
1782
1790
1800
1812
1822
1832
1840
1850
1860
1870
1882
1892
1902
1910
1922
1932
1940
1950
1963
1972
1980
1990
2000
2012
2022
2032
2040
2053
2062
2070
2080
2090
2102
2112
2122
2130
2140
2150
2160
2172
2182
2192
2200
2212
2222
2230
2240
2253
2262
2270
2280
2290
2302
2312
2322
2330
2343
2352
2360
2370
2380
2392
2400
2410
2420
2430
2442
2452
2462
2472
2482
2490
2502
2512
2522
2532
2540
2550
2563
2572
2580
2590
2600
2612
2622
2632
2640
2653
2662
2670
2680
2690
2702
2712
2722
2730
2743
2752
2760
2770
2780
2792
2802
2812
2820
2833
2842
2850
2860
2870
2882
2892
2902
2910
2920
2930
2940
2952
2962
2972
2980
2990
3003
3012
3020
3030
3042
3052
3062
3070
3083
3092
3100
3110
3122
3132
3142
3150
3160
3170
3180
3191
3201
3210
3220
3231
3242
3250
3260
3271
3280
3292
3302
3310
3321
3330
3340
3352
3360
3372
3381
3390
3402
3410
3421
3430
3440
3452
3460
3471
3482
3490
3500
3512
3520
3530
3540
3550
3560
3571
3582
3590
module fluentasserts.core.basetype; public import fluentasserts.core.base; import fluentasserts.core.results; import std.string; import std.conv; import std.algorithm; struct ShouldBaseType(T) { private const T testData; private ValueEvaluation valueEvaluation; this(U)(U value) { valueEvaluation = value.evaluation; testData = value.value; } mixin ShouldCommons; mixin ShouldThrowableCommons; alias above = this.greaterThan; alias below = this.lessThan; alias within = this.between; auto equal(const T someValue, const string file = __FILE__, const size_t line = __LINE__) { addMessage(" equal `"); addValue(someValue.to!string); addMessage("`"); beginCheck; auto isSame = testData == someValue; static if(is( T == bool )) { auto expected = expectedValue ? someValue.to!string : (!someValue).to!string; } else { auto expected = expectedValue ? someValue.to!string : ("not " ~ someValue.to!string); } return result(isSame, new ExpectedActualResult(expected, testData.to!string), file, line); } auto greaterThan()(const T someValue, const string file = __FILE__, const size_t line = __LINE__) if(!is(T == bool)) { addMessage(" greater than `"); addValue(someValue.to!string); addMessage("`"); beginCheck; auto isGreater = testData > someValue; auto mode = isGreater ? "greater than" : "less than or equal to"; auto expectedMode = isGreater ? "less than or equal to" : "greater than"; Message[] msg = [ Message(false, "`"), Message(true, testData.to!string), Message(false, "` is " ~ mode ~ " `"), Message(true, someValue.to!string), Message(false, "`.") ]; return result(isGreater, msg, new ExpectedActualResult(expectedMode ~ " `" ~ someValue.to!string ~ "`", testData.to!string), file, line); } auto lessThan()(const T someValue, const string file = __FILE__, const size_t line = __LINE__) if(!is(T == bool)) { addMessage(" less than `"); addValue(someValue.to!string); addMessage("`"); beginCheck; auto isLess = testData < someValue; Message[] msg = [ Message(false, "`"), Message(true, testData.to!string), Message(false, isLess ? "` is less than `" : "` is greater or equal to `"), Message(true, someValue.to!string), Message(false, "`.") ]; auto expectedMode = isLess ? "greater or equal to" : "less than"; return result(isLess, msg, new ExpectedActualResult(expectedMode ~ " `" ~ someValue.to!string ~ "`", testData.to!string), file, line); } auto between()(const T limit1, const T limit2, const string file = __FILE__, const size_t line = __LINE__) if(!is(T == bool)) { T min = limit1 < limit2 ? limit1 : limit2; T max = limit1 > limit2 ? limit1 : limit2; addMessage(" between `"); addValue(min.to!string); addMessage("` and `"); addValue(max.to!string); addMessage("`"); beginCheck; auto isLess = testData <= min; auto isGreater = testData >= max; auto isBetween = !isLess && !isGreater; Message[] msg; auto interval = "a value " ~ (expectedValue ? "inside" : "outside") ~ " (" ~ min.to!string ~ ", " ~ max.to!string ~ ") interval"; if(expectedValue) { msg ~= [ Message(false, "`"), Message(true, testData.to!string), Message(false, "`") ]; if(isLess) { msg ~= [ Message(false, " is less than or equal to `"), Message(true, min.to!string), Message(false, "`.") ]; } if(isGreater) { msg ~= [ Message(false, " is greater than or equal to `"), Message(true, max.to!string), Message(false, "`.") ]; } } return result(isBetween, msg, new ExpectedActualResult(interval, testData.to!string), file, line); } auto approximately()(const T someValue, const T delta, const string file = __FILE__, const size_t line = __LINE__) if(!is(T == bool)) { addMessage(" equal `"); addValue(someValue.to!string ~ "±" ~ delta.to!string); addMessage("`"); beginCheck; return between(someValue - delta, someValue + delta, file, line); } } @("numbers equal") unittest { ({ 5.should.equal(5); 5.should.not.equal(6); }).should.not.throwAnyException; auto msg = ({ 5.should.equal(6); }).should.throwException!TestException.msg; msg.split("\n")[0].should.equal("5 should equal `6`."); msg.split("\n")[2].strip.should.equal("Expected:6"); msg.split("\n")[3].strip.should.equal("Actual:5"); msg = ({ 5.should.not.equal(5); }).should.throwException!TestException.msg; msg.split("\n")[0].should.equal("5 should not equal `5`."); msg.split("\n")[2].strip.should.equal("Expected:not 5"); msg.split("\n")[3].strip.should.equal("Actual:5"); } @("bools equal") unittest { ({ true.should.equal(true); true.should.not.equal(false); }).should.not.throwAnyException; auto msg = ({ true.should.equal(false); }).should.throwException!TestException.msg; msg.split("\n")[0].should.equal("true should equal `false`."); msg.split("\n")[2].strip.should.equal("Expected:false"); msg.split("\n")[3].strip.should.equal("Actual:true"); msg = ({ true.should.not.equal(true); }).should.throwException!TestException.msg; msg.split("\n")[0].should.equal("true should not equal `true`."); msg.split("\n")[2].strip.should.equal("Expected:false"); msg.split("\n")[3].strip.should.equal("Actual:true"); } @("numbers greater than") unittest { ({ 5.should.be.greaterThan(4); 5.should.not.be.greaterThan(6); 5.should.be.above(4); 5.should.not.be.above(6); }).should.not.throwAnyException; auto msg = ({ 5.should.be.greaterThan(5); 5.should.be.above(5); }).should.throwException!TestException.msg; msg.split("\n")[0].should.equal("5 should be greater than `5`. `5` is less than or equal to `5`."); msg.split("\n")[2].strip.should.equal("Expected:greater than `5`"); msg.split("\n")[3].strip.should.equal("Actual:5"); msg = ({ 5.should.not.be.greaterThan(4); 5.should.not.be.above(4); }).should.throwException!TestException.msg; msg.split("\n")[0].should.equal("5 should not be greater than `4`. `5` is greater than `4`."); msg.split("\n")[2].strip.should.equal("Expected:less than or equal to `4`"); msg.split("\n")[3].strip.should.equal("Actual:5"); } @("numbers less than") unittest { ({ 5.should.be.lessThan(6); 5.should.not.be.lessThan(4); 5.should.be.below(6); 5.should.not.be.below(4); }).should.not.throwAnyException; auto msg = ({ 5.should.be.lessThan(4); 5.should.be.below(4); }).should.throwException!TestException.msg; msg.split("\n")[0].should.equal("5 should be less than `4`. `5` is greater or equal to `4`."); msg.split("\n")[2].strip.should.equal("Expected:less than `4`"); msg.split("\n")[3].strip.should.equal("Actual:5"); msg = ({ 5.should.not.be.lessThan(6); 5.should.not.be.below(6); }).should.throwException!TestException.msg; msg.split("\n")[0].should.equal("5 should not be less than `6`. `5` is less than `6`."); } @("numbers between") unittest { ({ 5.should.be.between(4, 6); 5.should.be.between(6, 4); 5.should.not.be.between(5, 6); 5.should.not.be.between(4, 5); 5.should.be.within(4, 6); 5.should.be.within(6, 4); 5.should.not.be.within(5, 6); 5.should.not.be.within(4, 5); }).should.not.throwAnyException; auto msg = ({ 5.should.be.between(5, 6); 5.should.be.within(5, 6); }).should.throwException!TestException.msg; msg.split("\n")[0].should.equal("5 should be between `5` and `6`. `5` is less than or equal to `5`."); msg.split("\n")[2].strip.should.equal("Expected:a value inside (5, 6) interval"); msg.split("\n")[3].strip.should.equal("Actual:5"); msg = ({ 5.should.be.between(4, 5); 5.should.be.within(4, 5); }).should.throwException!TestException.msg; msg.split("\n")[0].should.equal("5 should be between `4` and `5`. `5` is greater than or equal to `5`."); msg.split("\n")[2].strip.should.equal("Expected:a value inside (4, 5) interval"); msg.split("\n")[3].strip.should.equal("Actual:5"); msg = ({ 5.should.not.be.between(4, 6); 5.should.not.be.within(4, 6); }).should.throwException!TestException.msg; msg.split("\n")[0].strip.should.equal("5 should not be between `4` and `6`."); msg.split("\n")[2].strip.should.equal("Expected:a value outside (4, 6) interval"); msg.split("\n")[3].strip.should.equal("Actual:5"); msg = ({ 5.should.not.be.between(6, 4); 5.should.not.be.within(6, 4); }).should.throwException!TestException.msg; msg.split("\n")[0].strip.should.equal("5 should not be between `4` and `6`."); msg.split("\n")[2].strip.should.equal("Expected:a value outside (4, 6) interval"); msg.split("\n")[3].strip.should.equal("Actual:5"); } @("numbers approximately") unittest { ({ (10f/3f).should.be.approximately(3, 0.34); (10f/3f).should.not.be.approximately(3, 0.24); }).should.not.throwAnyException; auto msg = ({ (10f/3f).should.be.approximately(3, 0.3); }).should.throwException!TestException.msg; msg.split("\n")[0].strip.should.equal("(10f/3f) should be equal `3±0.3`. `3.33333` is greater than or equal to `3.3`."); msg.split("\n")[2].strip.should.equal("Expected:a value inside (2.7, 3.3) interval"); msg.split("\n")[3].strip.should.equal("Actual:3.33333"); msg = ({ (10f/3f).should.not.be.approximately(3, 0.34); }).should.throwException!TestException.msg; msg.split("\n")[0].strip.should.equal("(10f/3f) should not be equal `3±0.34`."); msg.split("\n")[2].strip.should.equal("Expected:a value outside (2.66, 3.34) interval"); msg.split("\n")[3].strip.should.equal("Actual:3.33333"); } /// should throw exceptions for delegates that return basic types unittest { int value() { throw new Exception("not implemented"); } void voidValue() { throw new Exception("not implemented"); } void noException() { } value().should.throwAnyException.withMessage.equal("not implemented"); voidValue().should.throwAnyException.withMessage.equal("not implemented"); bool thrown; try { noException.should.throwAnyException; } catch (TestException e) { e.msg.should.startWith("noException should throw any exception. Nothing was thrown."); thrown = true; } thrown.should.equal(true); thrown = false; try { voidValue().should.not.throwAnyException; } catch(TestException e) { thrown = true; e.msg.split("\n")[0].should.equal("voidValue() should not throw any exception. An exception of type `object.Exception` saying `not implemented` was thrown."); } thrown.should.equal(true); } /// it should compile const comparison unittest { const actual = 42; actual.should.equal(42); }