/
lasersquad
/
DynamicArrays
Обзор
Документация
Войти
/
lasersquad
/
DynamicArrays
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
dynamicarrays/prj/Delphi/DynamicArraysOTests/DynamicArraysStringTest.pas
1 910 строк
54 KB
lasersquad0
added new tests
20 май 2026, 22:16
20 май 2026, 22:16
050c023
Код
Авторство
О чём код?
unit DynamicArraysStringTest; interface uses DUnitX.TestFramework,{ TestBase,} DynamicArrays; //, DynamicArraysBaseTest; type [TestFixture] TDynamicArraysStringTest<TT: constructor, THArray; InnerT:constructor> = class //(TDynamicArraysBaseTest<TT, InnerT>) private type TTestingArrayType = TT; private function FindProc(arr : THArray; i : Cardinal; FindData: Pointer): Integer; function Compare1(arr: THArray; i, j: Cardinal): Integer; function Compare2(Item1, Item2: InnerT): Integer; function IsTTBoolean: Boolean; function IsTTUnsigned: Boolean; procedure VerifySorting(arr: TTestingArrayType); procedure CopyArray(arr1, arr2: TTestingArrayType); function GetP(v: InnerT): Pointer; function CreateValue(const AValue: string): InnerT; protected array1: TTestingArrayType; array2: TTestingArrayType; public //[TearDownFixture] //procedure TearDownFixture; // this method is called when all tests of this fixture are executed. so we have to free objects from FObjects [Setup] procedure Setup; [TearDown] procedure TearDown; [Test] procedure TestEmpty1; [Test] procedure TestEmpty2; [Test] procedure TestCountOne; [Test] procedure TestUpdate; [Test] procedure TestZero; [Test] procedure TestSwap; [Test] procedure TestAddFillValues; [Test] procedure TestIndexOF1; [Test] [TestCase('TestIndexofA','4, 1, 2, 0')] // last figure is used for assers when TT=Boolean [TestCase('TestIndexofB','1,-1, 3, 0')] [TestCase('TestIndexofC','0, 3,-1, 1')] [TestCase('TestIndexofD','-13, 13, -1, 0')] procedure TestIndexOf2(const AValue1, AValue2, AValue3, AValue4: string); [Test] procedure TestCapacity1; [Test] procedure TestCapacity2; [Test] [TestCase('TestA','5,1')] [TestCase('TestB','4,3')] [TestCase('TestD','0,-1')] procedure TestAddTwoDiff(const AValue1, AValue2 : string); [Test] [TestCase('TestA','11, 11')] [TestCase('TestB',' 3999,3999')] [TestCase('TestC',' 0, 0')] //[TestCase('TestD','00000000, 0000000')] procedure TestAddTwoEqual(const AValue1, AValue2 : string); [Test] procedure TestGrow; [Test] procedure TestInsert1; [Test] procedure TestInsert2; [Test] procedure TestDeleteValue1; [Test] procedure TestDeleteValue2; [Test] procedure TestAddClearAdd1; [Test] procedure TestAddClearAdd2; { [Test] procedure TestSort1; [TestCase('TestA', '1;2;3;4;5, 1;2;3;4;5')] [TestCase('TestB', '5;4;3;2;1, 1;2;3;4;5')] [TestCase('TestC', '44;53;1;12;100;999;9, 1;9;12;44;53;100;999')] [TestCase('TestD', '44;44;44;44;44;44;9, ;9;44;44;44;44;44;44')] [TestCase('TestE', '9;1;9;1;9;1;9;1, 1;1;1;1;;9;9;9;9;;')] [TestCase('TestF', '15, 15')] [TestCase('TestG', '0, 0')] [TestCase('TestH', '0;0, 0;0')] [TestCase('TestK', '16;15, 15;16')] procedure TestSort2(AValue1, AValue2: string); } [Test] procedure TestQuickSort1; // <unsorted items> , <sorted items to verify> [TestCase('TestA', '1;2;3;4;5, 1;2;3;4;5')] [TestCase('TestB', '5;4;3;2;1, 1;2;3;4;5')] [TestCase('TestC', '44;53;1;12;100;999;9, 1;9;12;44;53;100;999')] [TestCase('TestD', '44;44;44;44;44;44;9, ;9;44;44;44;44;44;44')] [TestCase('TestE', '9;1;9;1;9;1;9;1, 1;1;1;1;;9;9;9;9;;')] [TestCase('TestF', '15, 15')] [TestCase('TestG', '0, 0')] [TestCase('TestH', '0;0, 0;0')] [TestCase('TestK', '16;15, 15;16')] procedure TestQuickSort2(AValue1, AValue2: string); [Test] procedure TestAddMany; [Test] procedure TestInsertMany; { procedure TestSelectionSortPerformance; procedure TestQuickSortPerformance; [Test(false)] procedure TestInsertSortPerformance; procedure TestShakerSortPerformance; procedure TestBubbleSortPerformance; } [Test] [Ignore('Ignore this test to save testing time')] procedure TestAllSortAlgsPerformance; // the same data array is sorted by 5 different sorting algs, time is measured // <unsorted items> , <value to find> , <value index to verify> [TestCase('TestA1', '1;2;3;4;5, 1 , 0')] [TestCase('TestA2', '1;2;3;4;5, 2 , 1')] [TestCase('TestA3', '1;2;3;4;5, 0 , -1')] [TestCase('TestA4', '5;4;3;2;1, 3 , 2')] [TestCase('TestA5', '5;4;3;2;1, 6 , -6')] [TestCase('TestA6', '5;4;3;2;1, 5 , 4')] [TestCase('TestA7', '5;4;3;2;1, 4 , 3')] [TestCase('TestA8', '5;4;3;2;6;1, 6 , 5')] [TestCase('TestC1', '44;53;1;12;100;109;9, 100, 5 ')] [TestCase('TestC2', '44;53;1;12;100;109;9, 109, 6 ')] [TestCase('TestC3', '44;53;1;12;100;109;9, 1000, -8 ')] [TestCase('TestD1', '44;44;44;44;44;44;9, 9 , 0 ')] [TestCase('TestD2', '44;44;44;44;44;44;9, 44 , 1 ')] [TestCase('TestD3', '44;44;44;44;44;44;9, 0 , -1 ')] [TestCase('TestE1', '9;1;9;1;9;1;9;1, 1, 0')] [TestCase('TestE2', '9;1;9;1;9;1;9;1, 9, 4')] [TestCase('TestE3', '9;1;9;1;9;1;9;1, 10, -9')] [TestCase('TestH', '15, 15, 0')] [TestCase('TestK1', '0, 0, 0')] [TestCase('TestK2', '0, 1, -2')] [TestCase('TestL1', '0;0, 0, 0')] [TestCase('TestL2', '0;0, -1, -1')] [TestCase('TestM', '16;15, 16, 1')] //[Ignore('temporary IMGORE')] [Category('QuickFindTests')] procedure TestQuickFind(AValue1, AValue2, AValue3: string); end; const ARRAYSIZE_FOR_SORTING = 50_000; implementation uses System.TypInfo, System.Generics.Defaults, SysUtils, Winapi.Windows, DynamicArraysUtils; procedure TDynamicArraysStringTest<TT, InnerT>.Setup; begin array1 := TTestingArrayType.Create; array2 := TTestingArrayType.Create; end; procedure TDynamicArraysStringTest<TT, InnerT>.TearDown; begin FreeAndNil(array1); FreeAndNil(array2); end; function TDynamicArraysStringTest<TT, InnerT>.GetP(v: InnerT): Pointer; var vs: string absolute v; va: AnsiString absolute v; begin if TypeInfo(InnerT) = TypeInfo(string) then Result := @(vs[1]) else if TypeInfo(InnerT) = TypeInfo(AnsiString) then Result := @(va[1]) else Result := @v; end; function TDynamicArraysStringTest<TT, InnerT>.CreateValue(const AValue: string): InnerT; var TypeDataPtr: PTypeData; TypeInfoPtr: PTypeInfo; TypeKind: TTypeKind; { I8: Int8 absolute Result; U8: UInt8 absolute Result; I16: Int16 absolute Result; U16: UInt16 absolute Result; I32: Int32 absolute Result; U32: UInt32 absolute Result; I64: Int64 absolute Result;} UStr: UnicodeString absolute Result; WStr: WideString absolute Result; AnsiStr: AnsiString absolute Result; ShortStr: ShortString absolute Result; //IntHArr: THArrayG<Integer> absolute Result; { IntTObj: TObject absolute Result; Pnter: Pointer absolute Result; Ch: AnsiChar absolute Result; WCh: WideChar absolute Result; flSingle: Single absolute Result; flDouble: Double absolute Result; flExtended: Extended absolute Result; flComp: Comp absolute Result; flCurrency: Currency absolute Result; Bool: Boolean absolute Result;} begin Result := InnerT.Create; TypeInfoPtr := TypeInfo(InnerT); TypeDataPtr := GetTypeData(TypeInfoPtr); TypeKind := GetTypeKind(InnerT); case TypeKind of tkWString: WStr := WideString(AValue); tkUString: UStr := UnicodeString(AValue); tkLString: AnsiStr := AnsiString(AValue); tkString : ShortStr:= ShortString(AValue); // tkChar: Ch := AnsiChar(AValue); // tkWChar: WCh := WideChar(AValue); else System.Assert(False, 'CreateValue<T>: Type kind is not supported'); end; end; procedure TDynamicArraysStringTest<TT, InnerT>.TestEmpty1; begin Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array1.Capacity); Assert.AreEqual(Cardinal(sizeof(InnerT)), array1.ItemSize); array1.Clear(); Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array1.Capacity); Assert.AreEqual(Cardinal(sizeof(InnerT)), array1.ItemSize); array1.ClearMem(); Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array1.Capacity); Assert.AreEqual(Cardinal(sizeof(InnerT)), array1.ItemSize); array1.Hold; Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array1.Capacity); Assert.AreEqual(Cardinal(sizeof(InnerT)), array1.ItemSize); array1.Zero; Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array1.Capacity); Assert.AreEqual(Cardinal(sizeof(string)), array1.ItemSize); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestEmpty2; var val: InnerT; begin Assert.WillRaise(procedure begin array1.Delete(0) end, ERangeError, 'd0'); Assert.WillRaise(procedure begin array1.Delete(1) end, ERangeError, 'd1'); Assert.WillRaise(procedure begin array1.Delete(2) end, ERangeError, 'd2'); Assert.WillRaise(procedure begin array1.Delete(10000) end, ERangeError, 'd10000'); Assert.WillRaise(procedure begin array1.GetAddr(0) end, ERangeError, 'g0'); Assert.WillRaise(procedure begin array1.GetAddr(1) end, ERangeError, 'g1'); Assert.WillRaise(procedure begin array1.GetAddr(2) end, ERangeError, 'g2'); Assert.WillRaise(procedure begin array1.GetAddr(10000) end, ERangeError, 'g10000'); Assert.WillRaise(procedure begin array1.Get(0, @val) end, ERangeError, 'g0'); Assert.WillRaise(procedure begin array1.Get(1, @val) end, ERangeError, 'g1'); Assert.WillRaise(procedure begin array1.Get(2, @val) end, ERangeError, 'g2'); Assert.WillRaise(procedure begin array1.Get(10000, @val) end, ERangeError, 'g10000'); Assert.WillRaise(procedure begin array1.Update(0, @val) end, ERangeError, 'u0'); Assert.WillRaise(procedure begin array1.Update(1, @val) end, ERangeError, 'u1'); Assert.WillRaise(procedure begin array1.Update(2, @val) end, ERangeError, 'u2'); Assert.WillRaise(procedure begin array1.Update(10000, @val) end, ERangeError, 'u10000'); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestCountOne; var val, val2, valTmp: InnerT; begin val := CreateValue('dfdf'); val2 := CreateValue('9999 8888'); array1.Add(GetP(val)); Assert.AreEqual(1, array1.Count); Assert.AreEqual(4, array1.Capacity); Assert.WillRaise(procedure begin array1.Delete(1) end, ERangeError, 'd1'); Assert.AreEqual(1, array1.Count); Assert.AreEqual(4, array1.Capacity); Assert.WillRaise(procedure begin array1.Delete(2) end, ERangeError, 'd2'); Assert.AreEqual(1, array1.Count); Assert.AreEqual(4, array1.Capacity); Assert.WillRaise(procedure begin array1.Delete(10000) end, ERangeError, 'd10000'); Assert.AreEqual(1, array1.Count); Assert.AreEqual(4, array1.Capacity); valTmp := val2; // workaround to allocate enough space in valTmp, val2 is longest string in this method array1.Get(0, GetP(valTmp)); Assert.AreEqual<InnerT>(val, valTmp); Assert.WillRaise(procedure begin array1.Get(1, @valTmp) end, ERangeError, 'g1'); Assert.WillRaise(procedure begin array1.Get(2, @valTmp) end, ERangeError, 'g2'); Assert.WillRaise(procedure begin array1.Get(10000, @valTmp) end, ERangeError, 'g10000'); Assert.AreEqual(1, array1.Count); Assert.AreEqual(4, array1.Capacity); //Assert.AreEqual<TT>(val, array1[0]); //Assert.WillRaise(procedure begin array1[1] end, ERangeError, 'g1'); //Assert.WillRaise(procedure begin array1[2] end, ERangeError, 'g2'); //Assert.WillRaise(procedure begin array1[10000] end, ERangeError, 'g10000'); //Assert.AreEqual(1, array1.Count); //Assert.AreEqual(4, array1.Capacity); Assert.WillNotRaiseAny(procedure begin array1.Update(0, GetP(val2)) end); Assert.WillRaise(procedure begin array1.Update(1, @val) end, ERangeError, 'u1'); Assert.WillRaise(procedure begin array1.Update(2, @val) end, ERangeError, 'u2'); Assert.WillRaise(procedure begin array1.Update(10000, @val) end, ERangeError, 'u10000'); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestUpdate; var val, val2, val3, valTmp: string; newVal0, newVal1, newVal2: string; begin val := '666'; val2 := '9999'; val3 := '15003'; array1.Insert(0, @val); array1.Insert(1, @val2); array1.Insert(2, @val3); array1.Get(0, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val2, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val3, valTmp); newVal0 := '1'; newVal1 := '22'; newVal2 := '444'; array1.Update(0, @newVal0); array1.Get(0, @valTmp); Assert.AreEqual(newVal0, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val2, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val3, valTmp); array1.Update(1, @newVal1); array1.Get(0, @valTmp); Assert.AreEqual(newVal0, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(newVal1, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val3, valTmp); array1.Update(2, @newVal2); array1.Get(0, @valTmp); Assert.AreEqual(newVal0, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(newVal1, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(newVal2, valTmp); Assert.AreEqual(3, array1.Count); Assert.AreEqual(4, array1.Capacity); Assert.WillRaise(procedure begin array1.Update(3, @newVal0) end, ERangeError, 'g1'); Assert.WillRaise(procedure begin array1.Update(4, @newVal0) end, ERangeError, 'g2'); Assert.WillRaise(procedure begin array1.Update(1000, @newVal0) end, ERangeError, 'g10000'); Assert.AreEqual(3, array1.Count); Assert.AreEqual(4, array1.Capacity); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestZero; var val, val2, val3, valTmp: string; newVal: string; i: Integer; begin Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array1.Capacity); array1.Zero; Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array1.Capacity); val := '666'; val2 := '9999'; val3 := '15003'; array1.Insert(0, @val); array1.Insert(1, @val2); array1.Insert(2, @val3); Assert.AreEqual(3, array1.Count); Assert.AreEqual(4, array1.Capacity); array1.Get(0, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val2, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val3, valTmp); array1.Zero; Assert.AreEqual(3, array1.Count); Assert.AreEqual(4, array1.Capacity); newVal := '0'; array1.Get(0, @valTmp); Assert.AreEqual(newVal, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(newVal, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(newVal, valTmp); val := '1'; val2 := '22'; val3 := '444'; array1.Insert(1, @val); array1.Get(1, @valTmp); Assert.AreEqual(val, valTmp); array1.Insert(3, @val2); array1.Get(3, @valTmp); Assert.AreEqual(val2, valTmp); array1.Insert(5, @val3); array1.Get(5, @valTmp); Assert.AreEqual(val3, valTmp); array1.Zero; newVal := '0'; for i := 0 to 5 do begin array1.Get(i, @valTmp); Assert.AreEqual(newVal, valTmp); end; Assert.AreEqual(6, array1.Count); Assert.AreEqual(8, array1.Capacity); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestSwap; var val0, val1, val2, valTmp: string; begin val0 := '666'; val1 := '9999'; val2 := '15003'; array1.Insert(0, @val0); array1.Insert(1, @val1); array1.Add(@val2); Assert.AreEqual(3, array1.Count); Assert.AreEqual(4, array1.Capacity); array1.Get(0, @valTmp); Assert.AreEqual(val0, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val1, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val2, valTmp); array1.Swap(0, 1); array1.Get(0, @valTmp); Assert.AreEqual(val1, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val0, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val2, valTmp); array1.Swap(0, 1); array1.Get(0, @valTmp); Assert.AreEqual(val0, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val1, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val2, valTmp); array1.Swap(1, 1); array1.Get(0, @valTmp); Assert.AreEqual(val0, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val1, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val2, valTmp); array1.Swap(2, 2); array1.Get(0, @valTmp); Assert.AreEqual(val0, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val1, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val2, valTmp); array1.Swap(1, 0); array1.Get(0, @valTmp); Assert.AreEqual(val1, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val0, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val2, valTmp); array1.Swap(0, 2); array1.Get(0, @valTmp); Assert.AreEqual(val2, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val0, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val1, valTmp); array1.Swap(2, 1); array1.Get(0, @valTmp); Assert.AreEqual(val2, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val1, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val0, valTmp); Assert.WillRaise(procedure begin array1.Swap(0, 3); end, ERangeError, 'index out of bounds 1'); Assert.WillRaise(procedure begin array1.Swap(1, 4); end, ERangeError, 'index out of bounds 2'); Assert.WillRaise(procedure begin array1.Swap(3, 3); end, ERangeError, 'index out of bounds 3'); Assert.WillRaise(procedure begin array1.Swap(3, 0); end, ERangeError, 'index out of bounds 4'); Assert.WillRaise(procedure begin array1.Swap(4, 0); end, ERangeError, 'index out of bounds 5'); Assert.WillRaise(procedure begin array1.Swap(10, 10); end, ERangeError, 'index out of bounds 6'); Assert.WillRaise(procedure begin array1.Swap(11, 109); end, ERangeError, 'index out of bounds 7'); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestDeleteValue1; var I: Integer; v, v2: string; begin for I := 0 to 9 do begin v := (i + 1).ToString; array1.Add(@v); array2.Add(@v); end; Assert.AreEqual(10, array1.Count); Assert.AreEqual(10, array2.Count); Assert.AreEqual(12, array1.Capacity); Assert.AreEqual(12, array2.Capacity); array1.Delete(0); array2.Delete(0); Assert.AreEqual(9, array1.Count); Assert.AreEqual(9, array2.Count); Assert.AreEqual(12, array1.Capacity); Assert.AreEqual(12, array2.Capacity); for I := 0 to 8 do begin array1.Get(i, @v); v2 := (i + 2).ToString; Assert.AreEqual(v2, v); end; Assert.WillRaise(procedure begin array1.Delete(array1.Count); end, ERangeError, 'DeleteCalue at Count'); // try to delete out of range element Assert.AreEqual(9, array1.Count); array1.Delete(array1.Count - 1); //try to delete last element in the array array2.Delete(array2.Count - 1); //try to delete last element in the array Assert.AreEqual(8, array1.Count); Assert.AreEqual(8, array2.Count); Assert.AreEqual(12, array1.Capacity); Assert.AreEqual(12, array2.Capacity); for I := 0 to 7 do begin array1.Get(i, @v); v2 := (i + 2).ToString; Assert.AreEqual(v, v2) end; end; procedure TDynamicArraysStringTest<TT, InnerT>.TestDeleteValue2; var I: Integer; v: string; begin for I := 1 to 5 do begin v := (i + 1).ToString; array1.Add(@v); end; Assert.AreEqual(5, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(0); Assert.AreEqual(4, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(0); Assert.AreEqual(3, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(0); Assert.AreEqual(2, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(0); Assert.AreEqual(1, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(0); Assert.AreEqual(0, array1.Count); Assert.AreEqual(8, array1.Capacity); Assert.WillRaise(procedure begin array1.Delete(0); end, ERangeError, 'DeleteCalue at 0'); // try to delete out of range element Assert.WillRaise(procedure begin array1.Delete(0); end, ERangeError, 'DeleteCalue at 0'); // try to delete out of range element for I := 1 to 5 do begin v := (i + 1).ToString; array1.Add(@v); end; Assert.AreEqual(5, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(1); Assert.AreEqual(4, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(1); Assert.AreEqual(3, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(1); Assert.AreEqual(2, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(1); Assert.AreEqual(1, array1.Count); Assert.AreEqual(8, array1.Capacity); Assert.WillRaise(procedure begin array1.Delete(1); end, ERangeError, 'DeleteCalue at 0'); // try to delete out of range element Assert.AreEqual(1, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Clear; for I := 1 to 5 do begin v := (i + 1).ToString; array1.Add(@v); end; Assert.AreEqual(5, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(array1.Count - 1); Assert.AreEqual(4, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(array1.Count - 1); Assert.AreEqual(3, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(array1.Count - 1); Assert.AreEqual(2, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(array1.Count - 1); Assert.AreEqual(1, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Delete(array1.Count - 1); Assert.AreEqual(0, array1.Count); Assert.AreEqual(8, array1.Capacity); Assert.WillRaise(procedure begin array1.Delete(array1.Count); end, ERangeError, 'DeleteCalue at 0'); // try to delete out of range element Assert.AreEqual(0, array1.Count); Assert.AreEqual(8, array1.Capacity); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestIndexOf1; var v, vv, vvv: string; begin v := '777'; // CreateValue<TT>(777); vv := '4'; //CreateValue<TT>(4); vvv := '0'; //CreateValue<TT>(0); Assert.AreEqual(-1, array1.IndexOf(nil)); Assert.AreEqual(-1, array1.IndexOf(@v)); Assert.AreEqual(-1, array1.IndexOfFrom(nil, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(nil, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(nil, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(nil, 1000)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 1000)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 1000)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 1000)); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestIndexOf2(const AValue1, AValue2, AValue3, AValue4: string); var v, vv, vvv, vcmp: string; Ind: Cardinal; bvvv : Boolean absolute vvv; begin Assert.AreNotEqual(AValue1, AValue2, 'AValue1 and AValue2 must not be equal in TestIndexOf2()!'); // if IsTTUnsigned AND ((AValue1 < 0) OR (AValue2 < 0) OR (AValue3 < 0)) then exit; v := AValue1; //CreateValue<TT>(AValue1); vv := AValue2; //CreateValue<TT>(AValue2); vvv := AValue3; //CreateValue<TT>(Avalue3); Ind := array1.Add(@v); Assert.AreEqual(0, Ind); array1.Get(Ind, @vcmp); Assert.AreEqual(v, vcmp); Assert.AreEqual(array1.IndexOf(@vcmp), array1.IndexOf(@v)); Ind := array1.Add(@vv); Assert.AreEqual(1, Ind); array1.Get(Ind, @vcmp); Assert.AreEqual(vv, vcmp); Assert.AreEqual(array1.IndexOf(@vcmp), array1.IndexOf(@vv)); (* if IsTTBoolean() then begin Assert.AreEqual(AValue4, array1.IndexOfFrom(true, 0)); // Assert.AreEqual(AValue4, array1.IndexOfFrom(true, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(true, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(true, 333)); Assert.AreEqual(AValue4, array1.IndexOfFrom(true, 0)); // Assert.AreEqual(AValue4, array1.IndexOfFrom(vv, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(true, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(true, 333)); Assert.AreEqual(true, bvvv); Assert.AreEqual(AValue4, array1.IndexOf(vvv)); Assert.AreEqual(AValue4, array1.IndexOfFrom(vvv, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(vvv, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(vvv, 333)); end else begin *) // classes (e.g. TObject) cannot be compared by Assert.AreEqual<TT> because it calls v.Equals(vv) // while v and vv are fake instances of TObject and calling any method raises an exception // if GetTypeKind(TT) = tkClass // then Assert.AreEqual(CreateInteger<TT>(v), CreateInteger<TT>(vv)) // else Assert.AreEqual(0, array1.IndexOfFrom(@v, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 333)); Assert.AreEqual(1, array1.IndexOfFrom(@vv, 0)); Assert.AreEqual(1, array1.IndexOfFrom(@vv, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 333)); Assert.AreEqual(-1, array1.IndexOf(@vvv)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 333)); // end; (*if GetTypeKind(TT) = tkClass then begin // for non-Class types nil is converted into 0 (zero) and produces incorrect assert results when AValue1 or Avalue2 is also = 0. Assert.AreEqual(-1, array1.IndexOfFrom(nil, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(nil, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(nil, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(nil, 555)); end;*) end; procedure TDynamicArraysStringTest<TT, InnerT>.TestInsert1; var I: Integer; val, val2: string; begin for I := 0 to 99 do begin val := (i + 1000).ToString; array1.Insert(0, @val); array2.Insert(0, @val); if array1.Count < 4 then Assert.AreEqual(4, array1.Capacity); if (array1.Count >= 4) AND (array1.Count < 8) then Assert.AreEqual(8, array1.Capacity); if (array1.Count >= 8) AND (array1.Count < 12) then Assert.AreEqual(12, array1.Capacity); if (array1.Count >= 12) AND (array1.Count < 28) then Assert.AreEqual(28, array1.Capacity); if (array1.Count >= 28) AND (array1.Count < 44) then Assert.AreEqual(44, array1.Capacity); if (array1.Count >= 44) AND (array1.Count < 60) then Assert.AreEqual(60, array1.Capacity); if (array1.Count >= 60) AND (array1.Count < 76) then Assert.AreEqual(76, array1.Capacity); if (array1.Count >= 76) AND (array1.Count < 95) then Assert.AreEqual(95, array1.Capacity); if (array1.Count >= 95) then Assert.AreEqual(118, array1.Capacity); end; Assert.AreEqual(118, array1.Capacity); Assert.AreEqual(118, array2.Capacity); Assert.AreEqual(100, array1.Count); Assert.AreEqual(100, array2.Count); for I := 0 to 99 do begin array1.Get(i, @val); val2 := (1100 - I - 1).ToString; Assert.AreEqual(val2, val); end end; procedure TDynamicArraysStringTest<TT, InnerT>.TestInsert2; var //I: Integer; v1, v2,v3, vv: string; begin v1 := '111'; v2 := '222'; v3 := '333'; array1.Add(@v1); Assert.AreEqual(4, array1.Capacity); array1.Add(@v3); Assert.AreEqual(4, array1.Capacity); array1.Insert(1, @v2); Assert.AreEqual(4, array1.Capacity); array1.Get(0, @v1); vv := '111'; Assert.AreEqual(vv, v1); array1.Get(1, @v1); vv := '222'; Assert.AreEqual(vv, v1); array1.Get(2, @v1); vv := '333'; Assert.AreEqual(vv, v1); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestQuickFind(AValue1, AValue2, AValue3: string); var token: string; I, Cnt: Integer; FindVal, valTmp: string; begin if IsTTUnsigned AND (StrToInt(Trim(AValue2)) < 0) then exit; Cnt := HGetTokenCount(AValue1, ';', False); for I := 1 to Cnt do begin token := HGetToken(AValue1, ';', False, i - 1); valTmp := Trim(token); array1.Add(@valTmp); end; array1.QuickSort(Compare1); VerifySorting(array1); FindVal := Trim(AValue2); Assert.AreEqual(StrToInt(Trim(AValue3)), array1.QuickFind(FindProc, @FindVal)); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestQuickSort1; var v, v2: string; begin Assert.AreEqual(0, array1.Count); array1.QuickSort(nil); // array is empty so QuickSort will NOT generate an exception that CompareProc is not set. v := '9'; array1.Add(@v); array1.QuickSort(nil); // array contains one element so QuickSort will NOT generate an exception that CompareProc is not set. array1.Add(@v); try array1.QuickSort(nil); // here will be exception because array is NOT empty Assert.Fail('We should not be here!'); except on E:Exception do Assert.AreEqual('Cannot sort without CompareProc!', e.Message) end; array1.Clear; array1.QuickSort(Compare1); Assert.AreEqual(0, array1.Count); v := '4'; array1.Add(@v); v := '3'; array1.Add(@v); v := '5'; array1.Add(@v); v := '7'; array1.Add(@v); array1.QuickSort(Compare1); array1.Get(0, @v); v2 := '3'; Assert.AreEqual(v2, v); array1.Get(1, @v); v2 := '4'; Assert.AreEqual(v2, v); array1.Get(2, @v); v2 := '5'; Assert.AreEqual(v2, v); array1.Get(3, @v); v2 := '7'; Assert.AreEqual(v2, v); array1.Clear; v := '4'; array1.Add(@v); v := '3'; array1.Add(@v); v := '7'; array1.Add(@v); v := '6'; array1.Add(@v); array1.QuickSort(Compare1); array1.Get(0, @v); v2 := '3'; Assert.AreEqual(v2, v); array1.Get(1, @v); v2 := '4'; Assert.AreEqual(v2, v); array1.Get(2, @v); v2 := '6'; Assert.AreEqual(v2, v); array1.Get(3, @v); v2 := '7'; Assert.AreEqual(v2, v); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestQuickSort2(AValue1, AValue2: string); var Cnt: Integer; I: Integer; token: string; v: string; cmp: IComparer<TT>; begin cmp := TComparer<TT>.Default; Cnt := HGetTokenCount(AValue1, ';', False); for I := 1 to Cnt do begin token := HGetToken(AValue1, ';', False, i - 1); v := Trim(token); array1.Add(@v); end; array1.QuickSort(Compare1); VerifySorting(array1); // for I := 1 to array1.Count - 1 do // Assert.isTrue(cmp.Compare(array1[i-1], array1[i]) <= 0); Assert.Pass('TestQuickSort2: success.'); end; { procedure TDynamicArraysStringTest<TT, InnerT>.TestSort1; var v, v3, v4, v5, v7: InnerT; begin // if GetTypeKind(TT) in FComparableTypes then // begin Assert.AreEqual(0, array1.Count); array1.Sort(nil); // no exception if CompareProc=nil and array contains <2 elements v5 := 5; array1.Add(@v4); Assert.AreEqual(1, array1.Count); array1.Sort(nil); // no exception if CompareProc=nil and array contains <2 elements array1.Clear; Assert.AreEqual(0, array1.Count); array1.Sort(Compare1); Assert.AreEqual(0, array1.Count); v5 := 5; array1.Add(@v4); Assert.AreEqual(1, array1.Count); array1.Sort(Compare1); array1.Clear; v4 := 4; v3 := 3; v7 := 7; v5 := 5; array1.Add(@v4); array1.Add(@v3); array1.Add(@v7); array1.Add(@v5); try array1.Sort(nil); except on E:Exception do Assert.AreEqual('Cannot sort without CompareProc!', E.Message); end; array1.Clear; array1.Add(@v4); array1.Add(@v3); array1.Add(@v7); array1.Add(@v5); array1.Sort(Compare1); array1.Get(0, @v); Assert.AreEqual<InnerT>(v3, v); array1.Get(1, @v); Assert.AreEqual<InnerT>(v4, v); array1.Get(2, @v); Assert.AreEqual<InnerT>(v5, v); array1.Get(3, @v); Assert.AreEqual<InnerT>(v7, v); // end; end; procedure TDynamicArraysStringTest<TT, InnerT>.TestSort2(AValue1, AValue2: string); var token: string; valTmp: InnerT; I: Integer; cmp: IComparer<InnerT>; begin cmp := TComparer<InnerT>.Default; for I := 1 to HGetTokenCount(AValue1, ';', False) do begin token := HGetToken(AValue1, ';', False, i - 1); valTmp := StrToInt(Trim(token)); array1.Add(@valTmp); end; array1.Sort(Compare1); VerifySorting(array1); //for I := 1 to array1.Count - 1 do // Assert.isTrue(cmp.Compare(array1[i-1], array1[i]) <= 0); // if Avalue1 and Avalue2 contain only one value then no Assert.isTrue called in for loop above. // and DUnitX generates a warning "No assertion were made duringhe test" // to eliminate such warning Assert.Pass is added below Assert.Pass('TestSort2: success.'); end; } procedure TDynamicArraysStringTest<TT, InnerT>.VerifySorting(arr: TT); var i: Cardinal; v, vv: InnerT; cmp: IComparer<InnerT>; begin cmp := TComparer<InnerT>.Default; for i := 1 to arr.Count - 1 do begin arr.Get(i - 1, @v); arr.Get(i, @vv); Assert.IsTrue(cmp.Compare(v, vv) <= 0, '*** Array is NOT sorted ***'); end; //Assert.Pass('VerifySorting: Array is properly sorted.'); end; { procedure TDynamicArraysStringTest<TT>.TestBubbleSortPerformance; var i: Integer; begin if GetTypeKind(TT) in FComparableTypes then begin array1.SetCapacity(ARRAYSIZE_FOR_SORTING); for i := 0 to ARRAYSIZE_FOR_SORTING - 1 do begin var r := random(10_000); array1.AddValue(CreateValue<TT>(r)); end; var start := GetTickCount; array1.BubbleSort(nil); TDUnitX.CurrentRunner.Log(Format('BubbleSort(%d) = %s', [ARRAYSIZE_FOR_SORTING, MillisecToStr(GetTickCount - start)])); VerifySorting(array1); end; end; { procedure TDynamicArraysStringTest<TT>.TestSelectionSortPerformance; var i: Integer; begin if GetTypeKind(TT) in FComparableTypes then begin array1.SetCapacity(ARRAYSIZE_FOR_SORTING); for i := 0 to ARRAYSIZE_FOR_SORTING - 1 do begin var r := random(10_000); array1.AddValue(CreateValue<TT>(r)); end; var start := GetTickCount; array1.SelectionSort(nil); TDUnitX.CurrentRunner.Log(Format('SelectionSort(%d) = %s', [ARRAYSIZE_FOR_SORTING, MillisecToStr(GetTickCount - start)])); VerifySorting(array1); end; end; } { procedure TDynamicArraysStringTest<TT>.TestShakerSortPerformance; var i: Integer; begin if GetTypeKind(TT) in FComparableTypes then begin array1.SetCapacity(ARRAYSIZE_FOR_SORTING); for i := 0 to ARRAYSIZE_FOR_SORTING - 1 do begin var r := random(10_000); array1.AddValue(CreateValue<TT>(r)); end; var start := GetTickCount; array1.ShakerSort(nil); TDUnitX.CurrentRunner.Log(Format('ShakerSort(%d) = %s', [ARRAYSIZE_FOR_SORTING, MillisecToStr(GetTickCount - start)])); VerifySorting(array1); end; end; { procedure TDynamicArraysStringTest<TT>.TestQuickSortPerformance; var i: Integer; begin if GetTypeKind(TT) in FComparableTypes then begin array1.SetCapacity(ARRAYSIZE_FOR_SORTING); for i := 0 to ARRAYSIZE_FOR_SORTING - 1 do begin var r := random(10_000); array1.AddValue(CreateValue<TT>(r)); end; var start := GetTickCount; array1.QuickSort(nil); TDUnitX.CurrentRunner.Log(Format('QuickSort(%d) = %s', [ARRAYSIZE_FOR_SORTING, MillisecToStr(GetTickCount - start)])); VerifySorting(array1); end; end; procedure TDynamicArraysStringTest<TT>.TestInsertSortPerformance; var i: Integer; begin if GetTypeKind(TT) in FComparableTypes then begin array1.SetCapacity(ARRAYSIZE_FOR_SORTING); for i := 0 to ARRAYSIZE_FOR_SORTING - 1 do begin var r := random(10_000); array1.AddValue(CreateValue<TT>(r)); end; var start := GetTickCount; array1.InsertSort(nil); TDUnitX.CurrentRunner.Log(Format('InsertSort(%d) = %s', [ARRAYSIZE_FOR_SORTING, MillisecToStr(GetTickCount - start)])); VerifySorting(array1); end; end; } procedure TDynamicArraysStringTest<TT, InnerT>.CopyArray(arr1, arr2: TTestingArrayType); var i: Cardinal; v: InnerT; begin arr2.Clear; arr2.SetCapacity(arr1.Capacity); for i := 0 to arr1.Count - 1 do begin arr1.Get(i, @v); arr2.Add(@v); end; end; procedure TDynamicArraysStringTest<TT, InnerT>.TestAllSortAlgsPerformance; var i, l: Integer; r: string; begin array1.SetCapacity(ARRAYSIZE_FOR_SORTING); // then same initial array for all algs for i := 0 to ARRAYSIZE_FOR_SORTING - 1 do begin l := random(1000); // string length os random too r := GenerateRandomStr(l); array1.Add(@r{CreateValue<TT>(r)}); end; // we will be sorting array2 CopyArray(array1, array2); var start := GetTickCount; array2.BubbleSort(nil); TDUnitX.CurrentRunner.Log(Format('BubbleSort(%d) = %s', [ARRAYSIZE_FOR_SORTING, MillisecToStr(GetTickCount - start)])); VerifySorting(array2); CopyArray(array1, array2); start := GetTickCount; array2.SelectionSort(nil); TDUnitX.CurrentRunner.Log(Format('SelectingSort(%d) = %s', [ARRAYSIZE_FOR_SORTING, MillisecToStr(GetTickCount - start)])); VerifySorting(array2); {CopyArray(array1, array2); start := GetTickCount; array2.InsertSort(nil); TDUnitX.CurrentRunner.Log(Format('InsertSort(%d) = %s', [ARRAYSIZE_FOR_SORTING, MillisecToStr(GetTickCount - start)])); VerifySorting(array2);} CopyArray(array1, array2); start := GetTickCount; array2.ShakerSort(nil); TDUnitX.CurrentRunner.Log(Format('ShakerSort(%d) = %s', [ARRAYSIZE_FOR_SORTING, MillisecToStr(GetTickCount - start)])); VerifySorting(array2); CopyArray(array1, array2); start := GetTickCount; array2.QuickSort(nil); TDUnitX.CurrentRunner.Log(Format('QuiuckSort(%d) = %s', [ARRAYSIZE_FOR_SORTING, MillisecToStr(GetTickCount - start)])); VerifySorting(array2); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestCapacity1; begin Assert.AreEqual(0, array1.Capacity); array1.SetCapacity(1); Assert.AreEqual(1, array1.Capacity); Assert.AreEqual(0, array1.Count); array1.SetCapacity(0); Assert.AreEqual(0, array1.Capacity); array1.SetCapacity(2); Assert.AreEqual(2, array1.Capacity); Assert.AreEqual(0, array1.Count); array1.SetCapacity(3); Assert.AreEqual(3, array1.Capacity); Assert.AreEqual(0, array1.Count); array1.SetCapacity(100_000_000); Assert.AreEqual(100_000_000, array1.Capacity); Assert.AreEqual(0, array1.Count); array1.SetCapacity(0); Assert.AreEqual(0, array1.Capacity); Assert.AreEqual(0, array1.Count); array1.SetCapacity(100); Assert.AreEqual(100, array1.Capacity); Assert.AreEqual(0, array1.Count); //array1.Zero; //Assert.AreEqual(100, array1.Capacity); array1.Clear(); Assert.AreEqual(100, array1.Capacity); array1.Hold; Assert.AreEqual(0, array1.Capacity); Assert.AreEqual(0, array1.Count); array1.SetCapacity(200); array1.ClearMem(); Assert.AreEqual(0, array1.Capacity); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestCapacity2; var i: Integer; v: string; begin for i := 0 to 499 do begin v := i.ToString; array1.Add(@v); end; Assert.AreEqual(556, array1.Capacity); array1.Hold(); Assert.AreEqual(500, array1.Capacity); array1.SetCapacity(600); Assert.AreEqual(600, array1.Capacity); Assert.AreEqual(500, array1.Count); array1.SetCapacity(400); Assert.AreEqual(400, array1.Capacity); Assert.AreEqual(400, array1.Count); array1.SetCapacity(0); Assert.AreEqual(0, array1.Capacity); Assert.AreEqual(0, array1.Count); end; function TDynamicArraysStringTest<TT, InnerT>.Compare1(arr: THArray; i, j: Cardinal): Integer; const cmp: IComparer<InnerT> = nil; // analogue of static variable which saves its value between function calls var v1, v2: InnerT; begin if NOT Assigned(cmp) then cmp := TComparer<InnerT>.Default; // should be called only once arr.Get(i, @v1); arr.Get(j, @v2); Result := cmp.Compare(v1, v2); end; function TDynamicArraysStringTest<TT, InnerT>.FindProc(arr: THArray; i: Cardinal; FindData: Pointer): Integer; const cmp: IComparer<InnerT> = nil; // analogue of static variable which saves its value between function calls type PInnerT = ^InnerT; var v1, v2: InnerT; begin if NOT Assigned(cmp) then cmp := TComparer<InnerT>.Default; // should be called only once v1 := PInnerT(FindData)^; arr.Get(i, @v2); Result := cmp.Compare(v1, v2); end; function TDynamicArraysStringTest<TT, InnerT>.Compare2(Item1, Item2: InnerT): Integer; const cmp: IComparer<InnerT> = nil; // analogue of static variable which saves its value between function calls begin if NOT Assigned(cmp) then cmp := TComparer<InnerT>.Default; // should be called only once Result := cmp.Compare(Item1, Item2); end; function TDynamicArraysStringTest<TT, InnerT>.IsTTBoolean: Boolean; var TypeInfoPtr: PTypeInfo; begin TypeInfoPtr := TypeInfo(TT); Result := (GetTypeKind(TT) = tkEnumeration) AND (TypeInfoPtr.Name = 'Boolean'); end; function TDynamicArraysStringTest<TT, InnerT>.IsTTUnsigned: Boolean; var TypeInfoPtr: PTypeInfo; begin TypeInfoPtr := TypeInfo(InnerT); Result := (GetTypeKind(InnerT) = tkInteger) AND ((TypeInfoPtr.Name = 'Cardinal') OR (TypeInfoPtr.Name = 'LongWord') OR (TypeInfoPtr.Name = 'Word') OR (TypeInfoPtr.Name = 'NativeUint') OR (TypeInfoPtr.Name = 'UInt64')); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestAddClearAdd1; var I: Integer; v, v2: string; begin for I := 5 to 9 do begin v := I.ToString; array1.Insert(array1.Count, @v); array2.Insert(array2.Count, @v); end; Assert.AreEqual(8, array1.Capacity); Assert.AreEqual(8, array2.Capacity); Assert.AreEqual(5, array1.Count); Assert.AreEqual(5, array2.Count); array1.ClearMem; array2.ClearMem; Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array2.Count); Assert.AreEqual(0, array1.Capacity); Assert.AreEqual(0, array2.Capacity); for I := 15 to 19 do begin v := I.ToString; array1.Insert(array1.Count, @v); array2.Insert(array2.Count, @v); end; Assert.AreEqual(8, array1.Capacity); Assert.AreEqual(8, array2.Capacity); Assert.AreEqual(5, array1.Count); Assert.AreEqual(5, array2.Count); for I := 0 to 4 do begin array2.Get(I, @v); v2 := (I + 15).ToString; Assert.AreEqual(v2, v); end; for I := 0 to 4 do begin array2.Get(I, @v2); array1.Get(I, @v); Assert.AreEqual(v2, v); end; end; procedure TDynamicArraysStringTest<TT, InnerT>.TestAddClearAdd2; var I: Integer; v, v2: string; begin if IsTTUnsigned then exit; for I := -9 to -5 do begin v := I.ToString; array1.Insert(array1.Count, @v); array2.Insert(array2.Count, @v); end; Assert.AreEqual(8, array1.Capacity); Assert.AreEqual(8, array2.Capacity); Assert.AreEqual(5, array1.Count); Assert.AreEqual(5, array2.Count); array1.Clear; array2.Clear; Assert.AreEqual(8, array1.Capacity); Assert.AreEqual(8, array2.Capacity); Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array2.Count); for I := -19 to -15 do begin v := I.ToString; array1.Insert(array1.Count, @v); array2.Insert(array2.Count, @v); end; Assert.AreEqual(8, array1.Capacity); Assert.AreEqual(8, array2.Capacity); Assert.AreEqual(5, array1.Count); Assert.AreEqual(5, array2.Count); for I := 0 to 4 do begin array2.Get(I, @v); v2 := (I - 19).ToString; Assert.AreEqual(v2, v); end; for I := 0 to 4 do begin array2.Get(I, @v2); array1.Get(I, @v); Assert.AreEqual(v2, v); end; end; procedure TDynamicArraysStringTest<TT, InnerT>.TestAddMany; var val, valTmp: string; val1, val2, val3: string; arr: TArray<string>; begin val := '999'; //CreateValue<TT>(999); array1.AddMany(@val, 0); Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array1.Capacity); array1.AddMany(nil, 0); Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array1.Capacity); array1.AddMany(@val, 1); Assert.AreEqual(1, array1.Count); Assert.AreEqual(4, array1.Capacity); array1.Get(0, @valTmp); Assert.AreEqual(val, valTmp); array1.Clear; SetLength(arr, 4); arr[0] := val; arr[1] := val; arr[2] := val; arr[3] := val; array1.AddMany(@(arr[0]), 4); Assert.AreEqual(4, array1.Count); Assert.AreEqual(4, array1.Capacity); array1.Get(0, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(3, @valTmp); Assert.AreEqual(val, valTMp); array1.Clear; val1 := '44'; //CreateValue<TT>(44); val2 := '105'; //CreateValue<TT>(105); val3 := '909'; //CreateValue<TT>(909); array1.Add(@val1); array1.Add(@val2); array1.Add(@val3); Assert.AreEqual(3, array1.Count); Assert.AreEqual(4, array1.Capacity); SetLength(arr, 5); arr[4] := val; array1.AddMany(@(arr[0]), 5); Assert.AreEqual(8, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Get(0, @valTmp); Assert.AreEqual(val1, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val2, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val3, valTmp); array1.Get(3, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(4, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(5, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(6, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(7, @valTmp); Assert.AreEqual(val, valTmp); array1.Clear; end; procedure TDynamicArraysStringTest<TT, InnerT>.TestAddFillValues; var i: Integer; val, valTmp: string; begin array1.AddFillValues(0); Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array1.Capacity); array1.AddFillValues(1); Assert.AreEqual(1, array1.Count); Assert.AreEqual(4, array1.Capacity); array1.Get(0, @valTmp); val := '0'; Assert.AreEqual(val, valTmp); array1.AddFillValues(4); Assert.AreEqual(5, array1.Count); Assert.AreEqual(8, array1.Capacity); val := '0'; for i := 0 to 4 do begin array1.Get(i, @valTmp); Assert.AreEqual(val, valTmp); end; end; procedure TDynamicArraysStringTest<TT, InnerT>.TestInsertMany; var val, valTmp: string; val1, val2, val3: string; arr: TArray<string>; begin val := '999'; array1.InsertMany(0, @val, 0); array1.InsertMany(1, @val, 0); Assert.AreEqual(0, array1.Count); Assert.AreEqual(0, array1.Capacity); array1.InsertMany(0, @val, 1); Assert.AreEqual(1, array1.Count); Assert.AreEqual(4, array1.Capacity); array1.Get(0, @valTmp); Assert.AreEqual(val, valTmp); array1.Clear; SetLength(arr, 4); arr[0] := val; arr[1] := val; arr[2] := val; arr[3] := val; array1.InsertMany(0, @(arr[0]), 4); Assert.AreEqual(4, array1.Count); Assert.AreEqual(4, array1.Capacity); array1.Get(0, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(3, @valTmp); Assert.AreEqual(val, valTmp); array1.Clear; val1 := '44'; val2 := '105'; val3 := '909'; array1.Add(@val1); array1.Add(@val2); array1.Add(@val3); Assert.AreEqual(3, array1.Count); Assert.AreEqual(4, array1.Capacity); SetLength(arr, 5); arr[4] := val; array1.InsertMany(1, @arr[0], 5); Assert.AreEqual(8, array1.Count); Assert.AreEqual(8, array1.Capacity); array1.Get(0, @valTmp); Assert.AreEqual(val1, valTmp); array1.Get(1, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(2, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(3, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(4, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(5, @valTmp); Assert.AreEqual(val, valTmp); array1.Get(6, @valTmp); Assert.AreEqual(val2, valTmp); array1.Get(7, @valTmp); Assert.AreEqual(val3, valTmp); array1.InsertMany(0, @arr[0], 5); Assert.AreEqual(13, array1.Count); Assert.AreEqual(13, array1.Capacity); array1.InsertMany(1, @arr[0], 5); Assert.AreEqual(18, array1.Count); Assert.AreEqual(29, array1.Capacity); array1.InsertMany(array1.Count, @arr[0], 5); Assert.AreEqual(23, array1.Count); Assert.AreEqual(29, array1.Capacity); Assert.WillRaise(procedure begin array1.InsertMany(array1.Count + 1, @arr[0], 5) end, ERangeError, 'insertMany1'); end; procedure TDynamicArraysStringTest<TT, InnerT>.TestAddTwoDiff(const AValue1, AValue2 : string); var v, vv, vvv, vTmp: string; cmp: IComparer<string>; begin //if IsTTUnsigned AND ((AValue1 < 0) OR (AValue2 < 0)) then exit; Assert.AreNotEqual(AValue1, AValue2, 'AValue1 and AValue2 must be not equal in TestAddTwoDiff()!'); v := AValue1; //CreateValue<TT>(AValue1); vv := AValue2; //CreateValue<TT>(AValue2); array1.Add(@v); array1.Add(@vv); array1.Get(0, @vTmp); Assert.AreEqual(v, vTmp); array1.Get(1, @vTmp); Assert.AreEqual(vv, vTmp); array1.Get(0, @vTmp); Assert.AreEqual(v, vTmp); Assert.WillRaise(procedure begin array1.GetAddr(2) end, ERangeError, 'get2'); Assert.WillRaise(procedure begin array1.GetAddr(3) end, ERangeError, 'get3'); Assert.WillRaise(procedure begin array1.GetAddr(11) end, ERangeError, 'get11'); Assert.AreEqual(0, array1.IndexOf(@v)); Assert.AreEqual(1, array1.IndexOf(@vv)); Assert.AreEqual(0, array1.IndexOfFrom(@v, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 3)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 555)); Assert.AreEqual(1, array1.IndexOfFrom(@vv, 0)); Assert.AreEqual(1, array1.IndexOfFrom(@vv, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 3)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 555)); cmp := TComparer<string>.Default; if (AValue1 <> '') AND (AValue2 <> '') then begin vvv := AValue1 + AValue2; if (cmp.Compare(vvv, v) <> 0) AND (cmp.Compare(vvv, vv) <> 0) then Assert.AreEqual(-1, array1.IndexOf(@vvv)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 555)); (*vvv := AValue1 - AValue2; if (cmp.Compare(vvv, v) <> 0) AND (cmp.Compare(vvv, vv) <> 0) then Assert.AreEqual(-1, array1.IndexOf(@vvv)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 555));*) end; end; procedure TDynamicArraysStringTest<TT, InnerT>.TestAddTwoEqual(const AValue1, AValue2: string); var v,vv,{vvv,} vTmp: string; s: string absolute v; ss: string absolute vv; //cmp: IComparer<InnerT>; begin Assert.AreEqual(AValue1, AValue2, 'AValue1 and AValue2 must be equal in TestAddTwoEqual()!'); v := AValue1; vv := AValue2; array1.Add(@v); array1.Add(@vv); Assert.AreEqual<string>(v, vv); array1.Get(1, @vTmp); Assert.AreEqual<string>(v, vTmp); array1.Get(0, @vTmp); Assert.AreEqual<string>(vv, vTmp); Assert.AreEqual(0, array1.IndexOf(@v)); Assert.AreEqual(0, array1.IndexOf(@vv)); array1.Get(0, @vTmp); Assert.AreEqual<string>(v, vTmp); array1.Get(1, @vTmp); Assert.AreEqual<string>(vv, vTmp); Assert.WillRaise(procedure begin array1.GetAddr(2) end, ERangeError, 'get2'); Assert.WillRaise(procedure begin array1.GetAddr(3) end, ERangeError, 'get3'); Assert.WillRaise(procedure begin array1.GetAddr(66) end, ERangeError, 'get66'); Assert.AreEqual(0, array1.IndexOfFrom(@v, 0)); Assert.AreEqual(1, array1.IndexOfFrom(@v, 1)); Assert.AreEqual(0, array1.IndexOfFrom(@vv, 0)); Assert.AreEqual(1, array1.IndexOfFrom(@vv, 1)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 3)); Assert.AreEqual(-1, array1.IndexOfFrom(@v, 555)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 3)); Assert.AreEqual(-1, array1.IndexOfFrom(@vv, 555)); (* cmp := TComparer<InnerT>.Default; if AValue1 <> 0 then begin vvv := AValue1 + AValue2; if (cmp.Compare(vvv, v) <> 0) AND (cmp.Compare(vvv, vv) <> 0) then begin Assert.AreEqual(-1, array1.IndexOf(@vvv)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 1)); end; Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 555)); vvv := AValue1 - AValue2; if (cmp.Compare(vvv, v) <> 0) AND (cmp.Compare(vvv, vv) <> 0) then begin Assert.AreEqual(-1, array1.IndexOf(@vvv)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 0)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 1)); end; Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 2)); Assert.AreEqual(-1, array1.IndexOfFrom(@vvv, 555)); end; *) end; procedure TDynamicArraysStringTest<TT, InnerT>.TestGrow; var i: Integer; v: string; begin Assert.AreEqual(0, array1.Capacity); v := '11'; array1.Add(@v); Assert.AreEqual(4, array1.Capacity); v := '22'; array1.Add(@v); v := '33'; array1.Add(@v); Assert.AreEqual(4, array1.Capacity); v := '44'; array1.Add(@v); Assert.AreEqual(8, array1.Capacity); v := '11'; array1.Add(@v); v := '55'; array1.Add(@v); v := '66'; array1.Add(@v); v := '77'; array1.Add(@v); Assert.AreEqual(12, array1.Capacity); v := '11'; array1.Add(@v); Assert.AreEqual(12, array1.Capacity); Assert.AreEqual(9, array1.Count); for i := 0 to 2 do begin v := (i + 11).ToString; array1.Add(@v); end; Assert.AreEqual(28, array1.Capacity); for i := 0 to 15 do begin v := (i + 11).ToString; array1.Add(@v); end; Assert.AreEqual(28, array1.Count); Assert.AreEqual(44, array1.Capacity); for i := 0 to 15 do begin v := (i + 11).ToString; array1.Add(@v); end; Assert.AreEqual(44, array1.Count); Assert.AreEqual(60, array1.Capacity); for i := 0 to 15 do begin v := (i + 11).ToString; array1.Add(@v); end; Assert.AreEqual(60, array1.Count); Assert.AreEqual(76, array1.Capacity); for i := 0 to 15 do begin v := (i + 11).ToString; array1.Add(@v); end; Assert.AreEqual(76, array1.Count); Assert.AreEqual(95, array1.Capacity); for i := 0 to 18 do begin v := (i + 11).ToString; array1.Add(@v); end; Assert.AreEqual(95, array1.Count); Assert.AreEqual(118, array1.Capacity); array1.Clear(); Assert.AreEqual(0, array1.Count); Assert.AreEqual(118, array1.Capacity); array1.GrowTo(100); Assert.AreEqual(0, array1.Count); Assert.AreEqual(118, array1.Capacity); end; initialization // TDUnitX.RegisterTestFixture(TDynamicArraysStringTest<THArrayString, string>); TDUnitX.RegisterTestFixture(TDynamicArraysStringTest<THArrayStringFix, string>); // TDUnitX.RegisterTestFixture(TDynamicArraysStringTest<THarrayAnsiStringFix, AnsiString>); // TDUnitX.RegisterTestFixture(TDynamicArraysStringTest<THArrayWideStrings, WideString>); //TDUnitX.RegisterTestFixture(TDynamicArraysStringTest<THarrayPointer, Pointer>); end.