unit uTestAttributeGenerator;
interface
uses
SysUtils,
Generics.Collections,
Spring.Collections;
type
TTestAttributeGenerator =
record
private
fName:
string;
fArgs: IList<TPair<
string,
string>>;
fIntf:
string;
fImpl:
string;
procedure EnsureGenerated;
public
constructor Create(
const Name:
string;
const Args: IList<TPair<
string,
string>>);
function GetIntf:
string;
function GetImpl:
string;
end;
implementation
uses
StrUtils;
const
AttributeName = '
$(Name)';
AttributeArg = '
$(Arg)';
ArgCount = '
$(ArgCount)';
ArgIndex = '
$(ArgIndex)';
ArgName = '
$(ArgName)';
ArgType = '
$(ArgType)';
ArgAssign = '
$(ArgAssign)';
ResolvedAttributeArg = ArgName + '
: ' + ArgType;
ResolvedAttributeArgMultiple = ResolvedAttributeArg + '
; ' + AttributeArg;
ResolvedArgAssign = '
FValues[' + ArgIndex + '
] := TValue.From<' + ArgType + '
>(' + ArgName + '
);';
ResolvedArgAssignMutli = ResolvedArgAssign + sLineBreak + '
' + ArgAssign;
AttributeTemplateIntf =
'
' + AttributeName + '
Attribute = class(TestCaseAttribute)' + sLineBreak +
'
public' + sLineBreak +
'
constructor Create(' + AttributeArg + '
);' + sLineBreak +
'
end;';
AttributeTemplateImpl =
'
{ ' + AttributeName + '
Attribute }' + sLineBreak +
'
' + sLineBreak +
'
constructor ' + AttributeName + '
Attribute.Create(' + AttributeArg + '
);' + sLineBreak +
'
begin' + sLineBreak +
'
SetLength(FValues, ' + ArgCount + '
);' + sLineBreak +
'
' + ArgAssign + sLineBreak +
'
end;';
{ TTestAttributeGenerator }
constructor TTestAttributeGenerator.Create(
const Name:
string;
const Args: IList<TPair<
string,
string>>);
begin
if Name = '
'
then
raise EArgumentException.Create('
Argument [Name] can''
t be empty');
if not Assigned(Args)
then
raise EArgumentNilException.Create('
Argument [Args] has to be assigned');
if Args.Count = 0
then
raise EArgumentException.Create('
Argument [Args] can''
t be empty');
fName :=
Name;
fArgs := Args;
fIntf := AttributeTemplateIntf;
fImpl := AttributeTemplateImpl;
end;
function TTestAttributeGenerator.GetIntf:
string;
begin
EnsureGenerated();
Result := fIntf;
end;
function TTestAttributeGenerator.GetImpl:
string;
begin
EnsureGenerated();
Result := fImpl;
end;
procedure TTestAttributeGenerator.EnsureGenerated;
var
i: Integer;
s:
string;
begin
if not Assigned(fArgs)
then
Exit;
// replace AttributeName
fIntf := StringReplace(fIntf, AttributeName, fName, [rfReplaceAll]);
fImpl := StringReplace(fImpl, AttributeName, fName, [rfReplaceAll]);
// replace Argument count
fIntf := StringReplace(fIntf, ArgCount, IntToStr(fArgs.Count), [rfReplaceAll]);
fImpl := StringReplace(fImpl, ArgCount, IntToStr(fArgs.Count), [rfReplaceAll]);
for i := 0
to Pred(fArgs.Count)
do
begin
// replace Arg
s := IfThen(i = Pred(fArgs.Count), ResolvedAttributeArg, ResolvedAttributeArgMultiple);
fIntf := StringReplace(fIntf, AttributeArg, s, [rfReplaceAll]);
fImpl := StringReplace(fImpl, AttributeArg, s, [rfReplaceAll]);
// replace Assign
s := IfThen(i = Pred(fArgs.Count), ResolvedArgAssign, ResolvedArgAssignMutli);
fIntf := StringReplace(fIntf, ArgAssign, s, [rfReplaceAll]);
fImpl := StringReplace(fImpl, ArgAssign, s, [rfReplaceAll]);
// replace Argument Name
fIntf := StringReplace(fIntf, ArgName, fArgs[i].Key, [rfReplaceAll]);
fImpl := StringReplace(fImpl, ArgName, fArgs[i].Key, [rfReplaceAll]);
// replace Argument Type
fIntf := StringReplace(fIntf, ArgType, fArgs[i].Value, [rfReplaceAll]);
fImpl := StringReplace(fImpl, ArgType, fArgs[i].Value, [rfReplaceAll]);
// replace Argument Index
fIntf := StringReplace(fIntf, ArgIndex, IntToStr(i), [rfReplaceAll]);
fImpl := StringReplace(fImpl, ArgIndex, IntToStr(i), [rfReplaceAll]);
end;
fArgs :=
nil;
end;
end.