123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 |
- unit tclist;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, fpcunit, testutils, testregistry;
- type
- { TTestTList }
- TTestTList= class(TTestCase)
- private
- procedure AssertEquals(Msg: String; P1, P2: Pointer); overload;
- procedure DeleteNegativeIndex;
- procedure DeleteTooBigIndex;
- procedure ExchangeNegativeIndex1;
- procedure ExchangeNegativeIndex2;
- procedure ExchangeTooBigIndex1;
- procedure ExchangeTooBigIndex2;
- procedure AccessNegativeIndex;
- procedure AccessTooBigIndex;
- procedure Shuffle;
- protected
- List : TList;
- Pointers : Packed Array[0..20] of Byte;
- procedure SetUp; override;
- procedure TearDown; override;
- Procedure FillList(ACount : Integer);
- published
- procedure TestCreate;
- procedure TestAdd;
- procedure TestAddIndex;
- procedure TestAdd2;
- procedure TestInsertFirst;
- Procedure TestInsertMiddle;
- procedure TestDelete;
- Procedure TestClear;
- Procedure TestIndexOf;
- procedure TestExchange;
- procedure TestAccesIndexOutOfBounds;
- procedure TestDeleteIndexOutOfBounds;
- procedure TestExchangeIndexOutOfBounds;
- Procedure TestSort;
- procedure TestExtractCount;
- procedure TestExtractResult;
- procedure TestExtractNonExisting;
- procedure TestExtractNonExistingResult;
- procedure TestExtractOnlyFirst;
- Procedure TestNotifyAdd;
- Procedure TestNotifyDelete;
- Procedure TestNotifyExtract;
- Procedure TestPack;
- end;
- { TMyList }
- TMyList = Class(TList)
- procedure Notify(Ptr: Pointer; Action: TListNotification); override;
- FLastPointer : Pointer;
- FLastAction : TListNotification;
- end;
- implementation
- procedure TTestTList.SetUp;
- Var
- I : Integer;
- begin
- List:=TMyList.Create;
- For I:=0 to 20 do
- Pointers[i]:=I; // Zero serves as sentinel.
- end;
- procedure TTestTList.TearDown;
- begin
- FreeAndNil(List);
- end;
- procedure TTestTList.TestCreate;
- begin
- AssertEquals('Empty list has count 0',0,List.Count);
- end;
- procedure TTestTList.AssertEquals(Msg : String; P1,P2 : Pointer);
- begin
- If (P1<>P2) then
- Fail(Format('%s: Pointers differ. Expected <%x>, got: <%x>',[Msg,PtrInt(P1),PtrInt(P2)]));
- end;
- procedure TTestTList.TestAdd;
- begin
- FillList(1);
- AssertEquals('Add 1 element, count is 1',1,List.Count);
- AssertEquals('Add 1 element, last element is Ptrint(1)',@Pointers[1],List[0]);
- end;
- procedure TTestTList.TestAddIndex;
- begin
- AssertEquals('Add first element at index 0',0,List.Add(Nil));
- AssertEquals('Add second element, at index 1',1,List.Add(Nil));
- end;
- procedure TTestTList.TestAdd2;
- begin
- FillList(2);
- AssertEquals('Add 2 elements, count is 2',2,List.Count);
- AssertEquals('Add 2 elements, first element is Pointers[1]',@Pointers[1],List[0]);
- AssertEquals('Add 2 elements, second element is Pointers[2]',@Pointers[2],List[1]);
- end;
- procedure TTestTList.TestInsertFirst;
- begin
- FillList(3);
- List.Insert(0,@Pointers[0]);
- AssertEquals('Insert 1 in 3, count is 4',4,List.Count);
- AssertEquals('Insert 1 in 3, first is inserted',@Pointers[0],List[0]);
- AssertEquals('Insert 1 in 3, second is old first',@Pointers[1],List[1]);
- end;
- procedure TTestTList.TestInsertMiddle;
- begin
- FillList(3);
- List.Insert(1,@Pointers[0]);
- AssertEquals('Insert 1 in 3, count is 4',4,List.Count);
- AssertEquals('Insert 1 in 3, 1 is inserted',@Pointers[0],List[1]);
- AssertEquals('Insert 1 in 3, 2 is old 2',@Pointers[2],List[2]);
- AssertEquals('Insert 1 in 3, 0 is untouched',@Pointers[1],List[0]);
- end;
- procedure TTestTList.TestClear;
- begin
- FillList(3);
- List.Clear;
- AssertEquals('Clear: count is 0',0,List.Count);
- end;
- procedure TTestTList.TestIndexOf;
- begin
- FillList(11);
- AssertEquals('Find third element',2,List.IndexOf(@Pointers[3]));
- end;
- procedure TTestTList.TestDelete;
- begin
- FillList(3);
- List.Delete(1);
- AssertEquals('Delete 1 from 3, count is 2',2,List.Count);
- AssertEquals('Delete 1 from 3, first is pointers[1]',@Pointers[1],List[0]);
- AssertEquals('Delete 1 from 3, second is "pointers[3]',@Pointers[3],List[1]);
- end;
- procedure TTestTList.TestExchange;
- begin
- FillList(3);
- List.Exchange(0,2);
- AssertEquals('Exchange 0 and 2, count is 3',3,List.Count);
- AssertEquals('Exchange 0 and 2, first is Pointers[3]',@Pointers[3],List[0]);
- AssertEquals('Exchange 0 and 2, second is Pointers[2]',@Pointers[2],List[1]);
- AssertEquals('Exchange 0 and 2, third is Pointers[1]',@Pointers[1],List[2]);
- end;
- procedure TTestTList.DeleteNegativeIndex;
- begin
- List.Delete(-1);
- end;
- procedure TTestTList.DeleteTooBigIndex;
- begin
- List.Delete(3);
- end;
- procedure TTestTList.ExchangeNegativeIndex1;
- begin
- List.Exchange(-1,2);
- end;
- procedure TTestTList.ExchangeTooBigIndex1;
- begin
- List.Exchange(3,2);
- end;
- procedure TTestTList.ExchangeNegativeIndex2;
- begin
- List.Exchange(2,-1);
- end;
- procedure TTestTList.ExchangeTooBigIndex2;
- begin
- List.Exchange(2,3);
- end;
- procedure TTestTList.AccessNegativeIndex;
- begin
- List[-1];
- end;
- procedure TTestTList.AccessTooBigIndex;
- begin
- List[3];
- end;
- procedure TTestTList.Shuffle;
- Var
- I,I1,I2 : Integer;
- begin
- For I:=1 to List.Count* 2 do
- begin
- I1:=Random(List.Count);
- I2:=Random(List.Count);
- if I1<>I2 then
- List.Exchange(I1,I2);
- end;
- end;
- procedure TTestTList.TestAccesIndexOutOfBounds;
- begin
- FillList(3);
- AssertException('Access Negative Index',EListError,@AccessNegativeIndex);
- AssertException('Access Index too big',EListError,@AccessTooBigIndex);
- end;
- procedure TTestTList.TestDeleteIndexOutOfBounds;
- begin
- FillList(3);
- AssertException('Delete Negative Index',EListError,@DeleteNegativeIndex);
- AssertException('Delete Index too big',EListError,@DeleteTooBigIndex);
- end;
- procedure TTestTList.TestExchangeIndexOutOfBounds;
- begin
- FillList(3);
- AssertException('Exchange Negative first index',EListError,@ExchangeNegativeIndex1);
- AssertException('Exchange Negative second index',EListError,@ExchangeNegativeIndex2);
- AssertException('Exchange first Index too big',EListError,@ExchangeTooBigIndex1);
- AssertException('Exchange second Index too big',EListError,@ExchangeTooBigIndex2);
- end;
- Function CompareBytePointers(P1,P2 : Pointer) : Integer;
- begin
- Result:=PByte(P1)^-PByte(P2)^;
- end;
- procedure TTestTList.TestSort;
- Var
- I : Integer;
- begin
- FillList(9);
- Shuffle;
- List.Sort(@CompareBytePointers);
- For I:=0 to List.Count-1 do
- If (List[i]<>@Pointers[i+1]) then
- Fail(Format('Item at position %d is out of place (%d)',[I,PByte(List[i])^]));
- end;
- procedure TTestTList.TestExtractResult;
- Var
- I : Integer;
- begin
- FillList(9);
- AssertEquals('Extracting pointers[4]',@Pointers[4],List.Extract(@Pointers[4]));
- end;
- procedure TTestTList.TestExtractCount;
- Var
- I : Integer;
- begin
- FillList(9);
- List.Extract(@Pointers[4]);
- AssertEquals('Extracting pointers[4], count is 8',8,List.Count);
- end;
- procedure TTestTList.TestExtractNonExisting;
- Var
- I : Integer;
- begin
- FillList(9);
- List.Extract(@List);
- AssertEquals('Extracting unexisting, count remains 9',9,List.Count);
- end;
- procedure TTestTList.TestExtractNonExistingResult;
- Var
- I : Integer;
- begin
- FillList(9);
- AssertEquals('Extracting unexisting, result is nil',Nil,List.Extract(@List));
- end;
- procedure TTestTList.TestExtractOnlyFirst;
- Var
- I : Integer;
- begin
- FillList(9);
- List.Insert(0,@Pointers[4]);
- List.Extract(@Pointers[4]);
- AssertEquals('Extracting pointers[4], result is nil',3,List.IndexOf(@Pointers[4]));
- end;
- procedure TTestTList.TestNotifyAdd;
- begin
- List.Add(@Pointers[1]);
- AssertEquals('Add notification, pointer is pointer[1]',@Pointers[1],TMyList(List).FLastPointer);
- AssertEquals('Add notification, action is lnAdded',ord(lnAdded),Ord(TMyList(List).FLastAction));
- end;
- procedure TTestTList.TestNotifyDelete;
- begin
- FillList(9);
- List.Delete(3);
- AssertEquals('Delete notification, pointer is pointer[4]',@Pointers[4],TMyList(List).FLastPointer);
- AssertEquals('Delete notification, action is lnDeleted',ord(lnDeleted),Ord(TMyList(List).FLastAction));
- end;
- procedure TTestTList.TestNotifyExtract;
- begin
- FillList(9);
- List.Extract(@Pointers[4]);
- AssertEquals('Extract notification, pointer is pointer[4]',@Pointers[4],TMyList(List).FLastPointer);
- AssertEquals('Extract notification, action is lnExtracted',ord(lnExtracted),Ord(TMyList(List).FLastAction));
- end;
- procedure TTestTList.TestPack;
- Var
- I : integer;
- begin
- FillList(9);
- List[3]:=Nil;
- List[6]:=Nil;
- List.Pack;
- AssertEquals('Pack, count is 7',7,List.Count);
- For I:=0 to List.Count-1 do
- If (List[i]=Nil) then
- Fail(Format('Packed list contains nil pointer at position %d',[i]));
- AssertEquals('Packed list[3] is @pointer[5]',@Pointers[5],List[3]);
- AssertEquals('Packed list[6] is @pointer[9]',@pointers[9],List[6]);
- end;
- procedure TTestTList.FillList(ACount: Integer);
- Var
- I : integer;
- begin
- If ACount>20 then
- Fail('Too many elements added to list. Max is 20');
- For I:=1 to ACount do
- List.Add(@Pointers[i]);
- end;
- { TMyList }
- procedure TMyList.Notify(Ptr: Pointer; Action: TListNotification);
- begin
- inherited Notify(Ptr, Action);
- FLastAction:=Action;
- FLastPointer:=Ptr;
- end;
- initialization
- RegisterTest(TTestTList);
- end.
|