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;
Другие вопросы по тегам