fluentasserts.core.operations.registry 25/25(100%) line coverage

      
10
20
30
40
50
60
70
80
90
100
110
120
130
140
150
160
170
180
190
200
210
220
230
240
250
2672
2772
2812
290
300
310
3212
330
340
350
360
3712
3812
390
400
410
420
434398
440
454398
460
474398
480
490
500
510
524386
530
540
550
560
573520
583520
590
603520
610
623520
63697
640
651394
660
67694
680
690
703517
710
720
730
740
753520
760
770
780
790
803517
810
820
830
840
85697
860
870
880
891394
901394
911384
920
930
9410
950
module fluentasserts.core.operations.registry; import fluentasserts.core.results; import fluentasserts.core.evaluation; import std.functional; import std.string; /// Delegate type that can handle asserts alias Operation = IResult[] delegate(ref Evaluation) @safe nothrow; /// ditto alias OperationFunc = IResult[] delegate(ref Evaluation) @safe nothrow; /// class Registry { /// Global instance for the assert operations static Registry instance; private { Operation[string] operations; } /// Register a new assert operation Registry register(T, U)(string name, Operation operation) { foreach(valueType; extractTypes!T) { foreach(expectedValueType; extractTypes!U) { register(valueType, expectedValueType, name, operation); } } return this; } /// ditto Registry register(T, U)(string name, IResult[] function(ref Evaluation) @safe nothrow operation) { const operationDelegate = operation.toDelegate; return this.register!(T, U)(name, operationDelegate); } /// ditto Registry register(string valueType, string expectedValueType, string name, Operation operation) { string key = valueType ~ "." ~ expectedValueType ~ "." ~ name; operations[key] = operation; return this; } /// ditto Registry register(string valueType, string expectedValueType, string name, IResult[] function(ref Evaluation) @safe nothrow operation) { return this.register(valueType, expectedValueType, name, operation.toDelegate); } /// Get an operation function Operation get(string valueType, string expectedValueType, string name) @safe nothrow { assert(valueType != "", "The value type is not set!"); assert(name != "", "The operation name is not set!"); string key = valueType ~ "." ~ expectedValueType ~ "." ~ name; if(key !in operations) { auto genericKey = generalizeKey(valueType, expectedValueType, name); assert(key in operations || genericKey in operations, "There is no `" ~ key ~ "` or `" ~ genericKey ~ "` registered to the assert operations."); key = genericKey; } return operations[key]; } /// IResult[] handle(ref Evaluation evaluation) @safe nothrow { auto operation = this.get( evaluation.currentValue.typeName, evaluation.expectedValue.typeName, evaluation.operationName); return operation(evaluation); } } string generalizeKey(string valueType, string expectedValueType, string name) @safe nothrow { return generalizeType(valueType) ~ "." ~ generalizeType(expectedValueType) ~ "." ~ name; } string generalizeType(string typeName) @safe nothrow { auto pos = typeName.indexOf("["); if(pos == -1) { return "*"; } return "*" ~ typeName[pos..$]; }