DUnitX Преобразование из строки в массив целых
Мой вопрос похож на этот, но вместо набора я хотел бы передать массив целых чисел.
За пример:
[TestCase('TestAdd','[1,2,3,4];[1,2,3,4]',';')]
procedure TestAdd(aValue, aResult: array of integer);
Модификация DUnitX.Utils кажется самым чистым подходом, но я не уверен, как сделать преобразование. Мой главный вопрос: как он узнает, что мне нужен именно массив целых чисел? Есть ли в PTypeInfo что-то, чем я могу воспользоваться?
1 ответ
Вы не можете использовать открытый массив, потому что в RTTI отсутствует код для вызова методов с такими аргументами (которые реализуются фактически двумя аргументами под капотом). Так что вам нужно изменить подпись, чтобы использовать TArray<T>
или любой другой тип динамического массива.
Тогда модификация DUnitX.Utils действительно проста - просто добавьте эту функцию в массив Conversions для tkUString->tkDynArray (любая возможная оптимизация оставлена в качестве упражнения для читателя):
function ConvStr2DynArray(const ASource: TValue; ATarget: PTypeInfo; out AResult: TValue): Boolean;
var
s: string;
values: TStringDynArray;
i: Integer;
p: Pointer;
v1, v2: TValue;
elType: PTypeInfo;
begin
s := ASource.AsString;
if StartsStr('[', s) and EndsStr(']', s) then
s := Copy(s, 2, Length(s) - 2);
values := SplitString(s, ',');
i := Length(values);
p := nil;
DynArraySetLength(p, ATarget, 1, @i);
TValue.MakeWithoutCopy(@p, ATarget, AResult);
elType := ATarget.TypeData.DynArrElType^;
for i := 0 to High(values) do
begin
v1 := TValue.FromString(values[i]);
if not v1.TryConvert(elType, v2) then
Exit(False);
AResult.SetArrayElement(i, v2);
end;
Result := True;
end;