1020304050607080901001101201301401501601701801902002102202302402502602702802903003103213313403513603713803914014114214314414514614714814905015115205315415505615715815906016116216306416516606716816907017107207311741175076077078117911801181082118311841185086118711880890900910921193119411951196097098099010011101111021110301040105121106121107121108010912111012111112111201131211141211151211160117121118011901201112101220123012411251126012701284129013001311613216133013416135161361613701381613916140014101420143114411451146114701480149415041514152015301541155015611571158015911601161116211631164116511660167016801690170017101720173017401750176017701780179018032691810182326918301840185018601875169188018932671903267191019232641931819401950196324619701980199020032462012759202020302040205487206020702084872094872100211021248721302140 module fluentasserts.core.lifecycle; import fluentasserts.core.base; import fluentasserts.core.evaluation; import fluentasserts.core.operations.approximately; import fluentasserts.core.operations.arrayEqual; import fluentasserts.core.operations.beNull; import fluentasserts.core.operations.between; import fluentasserts.core.operations.contain; import fluentasserts.core.operations.endWith; import fluentasserts.core.operations.equal; import fluentasserts.core.operations.greaterThan; import fluentasserts.core.operations.greaterOrEqualTo; import fluentasserts.core.operations.instanceOf; import fluentasserts.core.operations.lessThan; import fluentasserts.core.operations.lessOrEqualTo; import fluentasserts.core.operations.registry; import fluentasserts.core.operations.startWith; import fluentasserts.core.operations.throwable; import fluentasserts.core.results; import fluentasserts.core.serializers; import std.meta; import std.conv; import std.datetime; alias BasicNumericTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real); alias NumericTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real/* , ifloat, idouble, ireal, cfloat, cdouble, creal, char, wchar, dchar*/); alias StringTypes = AliasSeq!(string, wstring, dstring, const(char)[]); static this() { SerializerRegistry.instance = new SerializerRegistry; Lifecycle.instance = new Lifecycle; ResultGlyphs.resetDefaults; Registry.instance = new Registry(); Registry.instance.describe("approximately", approximatelyDescription); Registry.instance.describe("equal", equalDescription); Registry.instance.describe("beNull", beNullDescription); Registry.instance.describe("between", betweenDescription); Registry.instance.describe("within", betweenDescription); Registry.instance.describe("contain", containDescription); Registry.instance.describe("greaterThan", greaterThanDescription); Registry.instance.describe("above", greaterThanDescription); Registry.instance.describe("greaterOrEqualTo", greaterOrEqualToDescription); Registry.instance.describe("lessThan", lessThanDescription); Registry.instance.register!(Duration, Duration)("lessThan", &lessThanDuration); Registry.instance.register!(Duration, Duration)("below", &lessThanDuration); Registry.instance.register!(SysTime, SysTime)("lessThan", &lessThanSysTime); Registry.instance.register!(SysTime, SysTime)("below", &lessThanSysTime); Registry.instance.register!(Duration, Duration)("greaterThan", &greaterThanDuration); Registry.instance.register!(Duration, Duration)("greaterOrEqualTo", &greaterOrEqualToDuration); Registry.instance.register!(Duration, Duration)("above", &greaterThanDuration); Registry.instance.register!(SysTime, SysTime)("greaterThan", &greaterThanSysTime); Registry.instance.register!(SysTime, SysTime)("greaterOrEqualTo", &greaterOrEqualToSysTime); Registry.instance.register!(SysTime, SysTime)("above", &greaterThanSysTime); Registry.instance.register!(Duration, Duration)("between", &betweenDuration); Registry.instance.register!(Duration, Duration)("within", &betweenDuration); Registry.instance.register!(SysTime, SysTime)("between", &betweenSysTime); Registry.instance.register!(SysTime, SysTime)("within", &betweenSysTime); Registry.instance.register("*", "*", "equal", &equal); static foreach(Type; NumericTypes) { Registry.instance.register(Type.stringof ~ "[]", Type.stringof ~ "[]", "equal", &arrayEqual); Registry.instance.register(Type.stringof ~ "[]", "void[]", "equal", &arrayEqual); } static foreach(Type; BasicNumericTypes) { Registry.instance.register(Type.stringof, Type.stringof, "greaterOrEqualTo", &greaterOrEqualTo!Type); Registry.instance.register(Type.stringof, Type.stringof, "greaterThan", &greaterThan!Type); Registry.instance.register(Type.stringof, Type.stringof, "above", &greaterThan!Type); Registry.instance.register(Type.stringof, Type.stringof, "lessOrEqualTo", &lessOrEqualTo!Type); Registry.instance.register(Type.stringof, Type.stringof, "lessThan", &lessThan!Type); Registry.instance.register(Type.stringof, Type.stringof, "below", &lessThan!Type); Registry.instance.register(Type.stringof, Type.stringof, "between", &between!Type); Registry.instance.register(Type.stringof, Type.stringof, "within", &between!Type); } /// special cases for .length and other comparisons with int types static foreach(Type; BasicNumericTypes) { Registry.instance.register(Type.stringof, "int", "lessOrEqualTo", &lessOrEqualTo!Type); Registry.instance.register(Type.stringof, "int", "lessThan", &lessThan!Type); Registry.instance.register(Type.stringof, "int", "greaterOrEqualTo", &greaterOrEqualTo!Type); Registry.instance.register(Type.stringof, "int", "greaterThan", &greaterThan!Type); } /// static foreach(Type1; NumericTypes) { Registry.instance.register(Type1.stringof ~ "[]", "void[]", "approximately", &approximatelyList); Registry.instance.register("*[]", "*", "contain", &arrayContain); Registry.instance.register("*[][]", "*[][]", "containOnly", &arrayContainOnly); static foreach(Type2; NumericTypes) { Registry.instance.register(Type1.stringof, Type2.stringof, "equal", &equal); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof ~ "[]", "equal", &arrayEqual); Registry.instance.register(Type1.stringof ~ "[]", "void[]", "equal", &arrayEqual); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof ~ "[]", "contain", &arrayContain); Registry.instance.register(Type1.stringof ~ "[]", "void[]", "contain", &arrayContain); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof, "contain", &arrayContain); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof ~ "[]", "containOnly", &arrayContainOnly); Registry.instance.register(Type1.stringof ~ "[]", "void[]", "containOnly", &arrayContainOnly); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof ~ "[]", "approximately", &approximatelyList); Registry.instance.register(Type1.stringof, Type2.stringof, "approximately", &approximately); } Registry.instance.register("object.Object[]", "object.Object[]", "containOnly", &arrayContainOnly); } Registry.instance.register("*[]", "*[]", "contain", &arrayContain); Registry.instance.register("*[]", "*[]", "containOnly", &arrayContainOnly); static foreach(Type1; StringTypes) { Registry.instance.register(Type1.stringof ~ "[]", "void[]", "equal", &arrayEqual); static foreach(Type2; StringTypes) { Registry.instance.register(Type1.stringof, Type2.stringof, "equal", &equal); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof ~ "[]", "equal", &arrayEqual); Registry.instance.register(Type1.stringof, Type2.stringof ~ "[]", "contain", &contain); Registry.instance.register(Type1.stringof, Type2.stringof, "contain", &contain); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof ~ "[]", "containOnly", &arrayContainOnly); Registry.instance.register(Type1.stringof, Type2.stringof, "startWith", &startWith); Registry.instance.register(Type1.stringof, Type2.stringof, "endWith", &endWith); } } Registry.instance.register("*[]", "*[]", "equal", &arrayEqual); Registry.instance.register("*[*]", "*[*]", "equal", &arrayEqual); Registry.instance.register("*[][]", "*[][]", "equal", &arrayEqual); Registry.instance.register("*", "*", "equal", &equal); static foreach(Type; StringTypes) { Registry.instance.register(Type.stringof, "char", "contain", &contain); Registry.instance.register(Type.stringof, "char", "startWith", &startWith); Registry.instance.register(Type.stringof, "char", "endWith", &endWith); } Registry.instance.register("*", "*", "instanceOf", &instanceOf); Registry.instance.register("callable", "", "throwAnyException", &throwAnyException); Registry.instance.register("callable", "", "throwException", &throwException); Registry.instance.register("*", "*", "throwAnyException", &throwAnyException); Registry.instance.register("*", "*", "throwAnyException.withMessage.equal", &throwAnyExceptionWithMessage); Registry.instance.register("*", "*", "throwException", &throwException); Registry.instance.register("*", "*", "throwException.withMessage.equal", &throwExceptionWithMessage); Registry.instance.register("*", "*", "throwSomething", &throwAnyException); Registry.instance.register("*", "*", "throwSomething.withMessage.equal", &throwAnyExceptionWithMessage); Registry.instance.register("*", "*", "beNull", &beNull); } /// The assert lifecycle @safe class Lifecycle { /// Global instance for the assert lifecicle static Lifecycle instance; private { /// int totalAsserts; } /// Method called when a new value is evaluated int beginEvaluation(ValueEvaluation value) @safe nothrow { totalAsserts++; return totalAsserts; } /// void endEvaluation(ref Evaluation evaluation) @trusted { if(evaluation.isEvaluated) return; evaluation.isEvaluated = true; auto results = Registry.instance.handle(evaluation); if(evaluation.currentValue.throwable !is null) { throw evaluation.currentValue.throwable; } if(evaluation.expectedValue.throwable !is null) { throw evaluation.currentValue.throwable; } if(results.length == 0) { return; } version(DisableSourceResult) {} else { results ~= evaluation.source; } if(evaluation.message !is null) { results = evaluation.message ~ results; } throw new TestException(results, evaluation.source.file, evaluation.source.line); } }
module fluentasserts.core.lifecycle; import fluentasserts.core.base; import fluentasserts.core.evaluation; import fluentasserts.core.operations.approximately; import fluentasserts.core.operations.arrayEqual; import fluentasserts.core.operations.beNull; import fluentasserts.core.operations.between; import fluentasserts.core.operations.contain; import fluentasserts.core.operations.endWith; import fluentasserts.core.operations.equal; import fluentasserts.core.operations.greaterThan; import fluentasserts.core.operations.greaterOrEqualTo; import fluentasserts.core.operations.instanceOf; import fluentasserts.core.operations.lessThan; import fluentasserts.core.operations.lessOrEqualTo; import fluentasserts.core.operations.registry; import fluentasserts.core.operations.startWith; import fluentasserts.core.operations.throwable; import fluentasserts.core.results; import fluentasserts.core.serializers; import std.meta; import std.conv; import std.datetime; alias BasicNumericTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real); alias NumericTypes = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real/* , ifloat, idouble, ireal, cfloat, cdouble, creal, char, wchar, dchar*/); alias StringTypes = AliasSeq!(string, wstring, dstring, const(char)[]); static this() { SerializerRegistry.instance = new SerializerRegistry; Lifecycle.instance = new Lifecycle; ResultGlyphs.resetDefaults; Registry.instance = new Registry(); Registry.instance.describe("approximately", approximatelyDescription); Registry.instance.describe("equal", equalDescription); Registry.instance.describe("beNull", beNullDescription); Registry.instance.describe("between", betweenDescription); Registry.instance.describe("within", betweenDescription); Registry.instance.describe("contain", containDescription); Registry.instance.describe("greaterThan", greaterThanDescription); Registry.instance.describe("above", greaterThanDescription); Registry.instance.describe("greaterOrEqualTo", greaterOrEqualToDescription); Registry.instance.describe("lessThan", lessThanDescription); Registry.instance.register!(Duration, Duration)("lessThan", &lessThanDuration); Registry.instance.register!(Duration, Duration)("below", &lessThanDuration); Registry.instance.register!(SysTime, SysTime)("lessThan", &lessThanSysTime); Registry.instance.register!(SysTime, SysTime)("below", &lessThanSysTime); Registry.instance.register!(Duration, Duration)("greaterThan", &greaterThanDuration); Registry.instance.register!(Duration, Duration)("greaterOrEqualTo", &greaterOrEqualToDuration); Registry.instance.register!(Duration, Duration)("above", &greaterThanDuration); Registry.instance.register!(SysTime, SysTime)("greaterThan", &greaterThanSysTime); Registry.instance.register!(SysTime, SysTime)("greaterOrEqualTo", &greaterOrEqualToSysTime); Registry.instance.register!(SysTime, SysTime)("above", &greaterThanSysTime); Registry.instance.register!(Duration, Duration)("between", &betweenDuration); Registry.instance.register!(Duration, Duration)("within", &betweenDuration); Registry.instance.register!(SysTime, SysTime)("between", &betweenSysTime); Registry.instance.register!(SysTime, SysTime)("within", &betweenSysTime); Registry.instance.register("*", "*", "equal", &equal); static foreach(Type; NumericTypes) { Registry.instance.register(Type.stringof ~ "[]", Type.stringof ~ "[]", "equal", &arrayEqual); Registry.instance.register(Type.stringof ~ "[]", "void[]", "equal", &arrayEqual); } static foreach(Type; BasicNumericTypes) { Registry.instance.register(Type.stringof, Type.stringof, "greaterOrEqualTo", &greaterOrEqualTo!Type); Registry.instance.register(Type.stringof, Type.stringof, "greaterThan", &greaterThan!Type); Registry.instance.register(Type.stringof, Type.stringof, "above", &greaterThan!Type); Registry.instance.register(Type.stringof, Type.stringof, "lessOrEqualTo", &lessOrEqualTo!Type); Registry.instance.register(Type.stringof, Type.stringof, "lessThan", &lessThan!Type); Registry.instance.register(Type.stringof, Type.stringof, "below", &lessThan!Type); Registry.instance.register(Type.stringof, Type.stringof, "between", &between!Type); Registry.instance.register(Type.stringof, Type.stringof, "within", &between!Type); } /// special cases for .length and other comparisons with int types static foreach(Type; BasicNumericTypes) { Registry.instance.register(Type.stringof, "int", "lessOrEqualTo", &lessOrEqualTo!Type); Registry.instance.register(Type.stringof, "int", "lessThan", &lessThan!Type); Registry.instance.register(Type.stringof, "int", "greaterOrEqualTo", &greaterOrEqualTo!Type); Registry.instance.register(Type.stringof, "int", "greaterThan", &greaterThan!Type); } /// static foreach(Type1; NumericTypes) { Registry.instance.register(Type1.stringof ~ "[]", "void[]", "approximately", &approximatelyList); Registry.instance.register("*[]", "*", "contain", &arrayContain); Registry.instance.register("*[][]", "*[][]", "containOnly", &arrayContainOnly); static foreach(Type2; NumericTypes) { Registry.instance.register(Type1.stringof, Type2.stringof, "equal", &equal); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof ~ "[]", "equal", &arrayEqual); Registry.instance.register(Type1.stringof ~ "[]", "void[]", "equal", &arrayEqual); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof ~ "[]", "contain", &arrayContain); Registry.instance.register(Type1.stringof ~ "[]", "void[]", "contain", &arrayContain); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof, "contain", &arrayContain); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof ~ "[]", "containOnly", &arrayContainOnly); Registry.instance.register(Type1.stringof ~ "[]", "void[]", "containOnly", &arrayContainOnly); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof ~ "[]", "approximately", &approximatelyList); Registry.instance.register(Type1.stringof, Type2.stringof, "approximately", &approximately); } Registry.instance.register("object.Object[]", "object.Object[]", "containOnly", &arrayContainOnly); } Registry.instance.register("*[]", "*[]", "contain", &arrayContain); Registry.instance.register("*[]", "*[]", "containOnly", &arrayContainOnly); static foreach(Type1; StringTypes) { Registry.instance.register(Type1.stringof ~ "[]", "void[]", "equal", &arrayEqual); static foreach(Type2; StringTypes) { Registry.instance.register(Type1.stringof, Type2.stringof, "equal", &equal); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof ~ "[]", "equal", &arrayEqual); Registry.instance.register(Type1.stringof, Type2.stringof ~ "[]", "contain", &contain); Registry.instance.register(Type1.stringof, Type2.stringof, "contain", &contain); Registry.instance.register(Type1.stringof ~ "[]", Type2.stringof ~ "[]", "containOnly", &arrayContainOnly); Registry.instance.register(Type1.stringof, Type2.stringof, "startWith", &startWith); Registry.instance.register(Type1.stringof, Type2.stringof, "endWith", &endWith); } } Registry.instance.register("*[]", "*[]", "equal", &arrayEqual); Registry.instance.register("*[*]", "*[*]", "equal", &arrayEqual); Registry.instance.register("*[][]", "*[][]", "equal", &arrayEqual); Registry.instance.register("*", "*", "equal", &equal); static foreach(Type; StringTypes) { Registry.instance.register(Type.stringof, "char", "contain", &contain); Registry.instance.register(Type.stringof, "char", "startWith", &startWith); Registry.instance.register(Type.stringof, "char", "endWith", &endWith); } Registry.instance.register("*", "*", "instanceOf", &instanceOf); Registry.instance.register("callable", "", "throwAnyException", &throwAnyException); Registry.instance.register("callable", "", "throwException", &throwException); Registry.instance.register("*", "*", "throwAnyException", &throwAnyException); Registry.instance.register("*", "*", "throwAnyException.withMessage.equal", &throwAnyExceptionWithMessage); Registry.instance.register("*", "*", "throwException", &throwException); Registry.instance.register("*", "*", "throwException.withMessage.equal", &throwExceptionWithMessage); Registry.instance.register("*", "*", "throwSomething", &throwAnyException); Registry.instance.register("*", "*", "throwSomething.withMessage.equal", &throwAnyExceptionWithMessage); Registry.instance.register("*", "*", "beNull", &beNull); } /// The assert lifecycle @safe class Lifecycle { /// Global instance for the assert lifecicle static Lifecycle instance; private { /// int totalAsserts; } /// Method called when a new value is evaluated int beginEvaluation(ValueEvaluation value) @safe nothrow { totalAsserts++; return totalAsserts; } /// void endEvaluation(ref Evaluation evaluation) @trusted { if(evaluation.isEvaluated) return; evaluation.isEvaluated = true; auto results = Registry.instance.handle(evaluation); if(evaluation.currentValue.throwable !is null) { throw evaluation.currentValue.throwable; } if(evaluation.expectedValue.throwable !is null) { throw evaluation.currentValue.throwable; } if(results.length == 0) { return; } version(DisableSourceResult) {} else { results ~= evaluation.source; } if(evaluation.message !is null) { results = evaluation.message ~ results; } throw new TestException(results, evaluation.source.file, evaluation.source.line); } }