-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAutoFixture.IdGenerator.pas
126 lines (103 loc) · 2.67 KB
/
AutoFixture.IdGenerator.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
unit AutoFixture.IdGenerator;
interface
uses
RTTI,
Generics.Collections,
AutofixtureGenerator;
type
TIdGenerator = class(TInterfacedObject, IValueGenerator)
private
FId : Integer;
public
procedure SetStartValue(AStartId: Integer);
function getValue(aPropertyName: String; aType: TRttiType; AReferenceDepth: integer = -1): TValue;
constructor Create;
end;
TidGeneratorAnyType = class(TInterfacedObject, IValueGenerator)
private
FIdDict: TDictionary<TRttiType, Integer>;
public
function getValue(aPropertyName: String; aType: TRttiType; AReferenceDepth: integer = -1): TValue;
constructor Create;
end;
implementation
uses SysUtils;
{ TIdGenerator }
constructor TIdGenerator.Create;
begin
FId := 1;
end;
function TIdGenerator.getValue(APropertyName: String; AType: TRttiType; AReferenceDepth: integer = -1): TValue;
var
vName: String;
begin
Result := TValue.Empty;
vName := UpperCase(aPropertyName);
if Assigned(AType) and (AType.TypeKind = tkInteger) and (vName.EndsWith('ID') or (vName = 'KEY')) then begin
Result := TValue.From<Integer>(Fid);
inc(FId);
end;
end;
procedure TIdGenerator.SetStartValue(AStartId: Integer);
begin
FId := AStartId;
end;
{ TidGeneratorAnyType }
constructor TidGeneratorAnyType.Create;
begin
FIdDict := TDictionary<TRttiType, Integer>.Create;
end;
function TidGeneratorAnyType.getValue(aPropertyName: String; aType: TRttiType; AReferenceDepth: integer = -1): TValue;
var
vId: Integer;
begin
Result := TValue.Empty;
if not FIdDict.TryGetValue(aType, vId) then begin
vId := 0;
FIdDict.Add(aType, vID);
end;
case aType.TypeKind of
tkInteger: begin
Result := TValue.From<Integer>(vId);
end;
tkInt64: begin
Result := TValue.From<Int64>(vId);
end;
tkChar: begin
Result := TValue.From<Char>(Chr(vId));
end;
tkWChar: begin
Result := TValue.From<WideChar>(Chr(vID));
end;
tkWString, tkUString, tkLString: begin
Result := TValue.From(IntToStr(vId));
end;
tkEnumeration: begin
Result := TValue.FromOrdinal(aType.Handle, aType.AsOrdinal.MinValue + vId);
end;
tkFloat: Begin
Result := TValue.From(0.1 + vId);
End;
tkVariant: Begin
Result := TValue.From(vId);
End;
tkSet: begin
// RTTI can't work with sets - ignore
end;
tkClass: begin
Result := TValue.From(aType.TypeKind);
end;
tkInterface: begin
end;
tkArray: begin
end;
tkRecord: begin
end;
tkDynArray: begin
end;
tkPointer: begin
end;
end;
FIdDict[AType] := vId + 1;
end;
end.