Browse Source

* More tests and reorganization per unit

git-svn-id: branches/cleanroom@9307 -
michael 18 years ago
parent
commit
cb5afd9b14

+ 5 - 2
.gitattributes

@@ -5522,16 +5522,19 @@ rtl/symbian/uiq.pas -text
 rtl/symbian/uiqclasses.pas -text
 rtl/symbian/uiqinc/qikapplication.inc -text
 rtl/symbian/uiqinc/qikapplicationoo.inc -text
-rtl/tests/findnested.lpi svneol=native#text/plain
-rtl/tests/findnested.lpr svneol=native#text/plain
 rtl/tests/fplists.pp svneol=native#text/plain
 rtl/tests/lists.pp svneol=native#text/plain
 rtl/tests/lltests.lpi svneol=native#text/plain
 rtl/tests/lltests.lpr svneol=native#text/plain
 rtl/tests/searchbuf.inc svneol=native#text/plain
+rtl/tests/tccollection.pp svneol=native#text/plain
 rtl/tests/tcfindnested.pp svneol=native#text/plain
+rtl/tests/tclist.pp svneol=native#text/plain
+rtl/tests/tcpersistent.pp svneol=native#text/plain
 rtl/tests/tcstringlist.pp svneol=native#text/plain
 rtl/tests/tcstrutils.pp svneol=native#text/plain
+rtl/tests/testclasses.lpi svneol=native#text/plain
+rtl/tests/testclasses.lpr svneol=native#text/plain
 rtl/tests/testll.pp svneol=native#text/plain
 rtl/tests/tstrutils.lpi svneol=native#text/plain
 rtl/tests/tstrutils.lpr svneol=native#text/plain

+ 0 - 164
rtl/tests/findnested.lpi

@@ -1,164 +0,0 @@
-<?xml version="1.0"?>
-<CONFIG>
-  <ProjectOptions>
-    <PathDelim Value="/"/>
-    <Version Value="6"/>
-    <General>
-      <MainUnit Value="0"/>
-      <TargetFileExt Value=""/>
-      <ActiveEditorIndexAtStart Value="0"/>
-    </General>
-    <VersionInfo>
-      <ProjectVersion Value=""/>
-      <Language Value=""/>
-      <CharSet Value=""/>
-    </VersionInfo>
-    <PublishOptions>
-      <Version Value="2"/>
-      <IgnoreBinaries Value="False"/>
-      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
-      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
-    </PublishOptions>
-    <RunParams>
-      <local>
-        <FormatVersion Value="1"/>
-        <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
-      </local>
-    </RunParams>
-    <RequiredPackages Count="2">
-      <Item1>
-        <PackageName Value="FPCUnitConsoleRunner"/>
-      </Item1>
-      <Item2>
-        <PackageName Value="FCL"/>
-      </Item2>
-    </RequiredPackages>
-    <Units Count="2">
-      <Unit0>
-        <Filename Value="findnested.lpr"/>
-        <IsPartOfProject Value="True"/>
-        <UnitName Value="findnested"/>
-        <UsageCount Value="20"/>
-      </Unit0>
-      <Unit1>
-        <Filename Value="tcfindnested.pp"/>
-        <IsPartOfProject Value="True"/>
-        <UnitName Value="tcfindnested"/>
-        <CursorPos X="1" Y="91"/>
-        <TopLine Value="61"/>
-        <EditorIndex Value="0"/>
-        <UsageCount Value="20"/>
-        <Loaded Value="True"/>
-      </Unit1>
-    </Units>
-    <JumpHistory Count="22" HistoryIndex="21">
-      <Position1>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="22" Column="17" TopLine="13"/>
-      </Position1>
-      <Position2>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="25" Column="102" TopLine="1"/>
-      </Position2>
-      <Position3>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="44" Column="27" TopLine="18"/>
-      </Position3>
-      <Position4>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="48" Column="7" TopLine="24"/>
-      </Position4>
-      <Position5>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="58" Column="1" TopLine="32"/>
-      </Position5>
-      <Position6>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="125" Column="5" TopLine="63"/>
-      </Position6>
-      <Position7>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="19" Column="38" TopLine="18"/>
-      </Position7>
-      <Position8>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="20" Column="33" TopLine="19"/>
-      </Position8>
-      <Position9>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="19" Column="29" TopLine="18"/>
-      </Position9>
-      <Position10>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="21" Column="34" TopLine="20"/>
-      </Position10>
-      <Position11>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="23" Column="28" TopLine="22"/>
-      </Position11>
-      <Position12>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="113" Column="1" TopLine="88"/>
-      </Position12>
-      <Position13>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="24" Column="30" TopLine="23"/>
-      </Position13>
-      <Position14>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="23" Column="28" TopLine="22"/>
-      </Position14>
-      <Position15>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="19" Column="32" TopLine="18"/>
-      </Position15>
-      <Position16>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="20" Column="35" TopLine="19"/>
-      </Position16>
-      <Position17>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="19" Column="35" TopLine="18"/>
-      </Position17>
-      <Position18>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="92" Column="1" TopLine="66"/>
-      </Position18>
-      <Position19>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="25" Column="28" TopLine="1"/>
-      </Position19>
-      <Position20>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="174" Column="28" TopLine="124"/>
-      </Position20>
-      <Position21>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="119" Column="1" TopLine="93"/>
-      </Position21>
-      <Position22>
-        <Filename Value="tcfindnested.pp"/>
-        <Caret Line="83" Column="1" TopLine="41"/>
-      </Position22>
-    </JumpHistory>
-  </ProjectOptions>
-  <CompilerOptions>
-    <Version Value="5"/>
-    <CodeGeneration>
-      <Generate Value="Faster"/>
-    </CodeGeneration>
-    <Other>
-      <CompilerPath Value="$(CompPath)"/>
-    </Other>
-  </CompilerOptions>
-  <Debugging>
-    <Exceptions Count="2">
-      <Item1>
-        <Name Value="ECodetoolError"/>
-      </Item1>
-      <Item2>
-        <Name Value="EFOpenError"/>
-      </Item2>
-    </Exceptions>
-  </Debugging>
-</CONFIG>

+ 12 - 15
rtl/tests/searchbuf.inc

@@ -20,7 +20,7 @@ begin
 end;
 
 function SearchDown(buf,aStart,endchar:pchar; SearchString:string;
-    equal : TEqualFunction; WholeWords:boolean) : pchar;
+    Equals : TEqualFunction; WholeWords:boolean) : pchar;
 var Found : boolean;
     s, c : pchar;
 begin
@@ -29,7 +29,7 @@ begin
   while not Found and (result <= endchar) do
     begin
     // Search first letter
-    while (result <= endchar) and not Equal(result^,SearchString[1]) do
+    while (result <= endchar) and not Equals(result^,SearchString[1]) do
       inc (result);
     // Check if following is searchstring
     c := result;
@@ -37,7 +37,7 @@ begin
     Found := true;
     while (c <= endchar) and (s^ <> #0) and Found do
       begin
-      Found := Equal(c^, s^);
+      Found := Equals(c^, s^);
       inc (c);
       inc (s);
       end;
@@ -53,18 +53,18 @@ begin
     result := nil;
 end;
 
-Function SearchUp(buf,aStart,endchar:pchar; SearchString:string;
-    equal : TEqualFunction; WholeWords:boolean) : pchar;
+function SearchUp(buf,aStart,endchar:pchar; SearchString:string;
+    equals : TEqualFunction; WholeWords:boolean) : pchar;
 var Found : boolean;
     s, c, l : pchar;
 begin
-  aStart := buf;
+  result := aStart;
   Found := false;
   l := @(SearchString[length(SearchString)]);
   while not Found and (result >= buf) do
     begin
     // Search last letter
-    while (result >= buf) and not Equal(result^,l^) do
+    while (result >= buf) and not Equals(result^,l^) do
       dec (result);
     // Check if before is searchstring
     c := result;
@@ -72,7 +72,7 @@ begin
     Found := true;
     while (c >= buf) and (s >= @SearchString[1]) and Found do
       begin
-      Found := Equal(c^, s^);
+      Found := Equals(c^, s^);
       dec (c);
       dec (s);
       end;
@@ -96,22 +96,19 @@ function SearchBuf(Buf: PChar;BufLen: Integer;SelStart: Integer;SelLength: Integ
 var
   equal : TEqualFunction;
 begin
-  {$ifdef noexception}
-  if SearchString = '' then
+  SelStart := SelStart + SelLength;
+  if (SearchString = '') or (SelStart > BufLen) or (SelStart < 0) then
     result := nil
   else
     begin
-  {$endif}
     if soMatchCase in Options then
       Equal := @EqualWithCase
     else
       Equal := @EqualWithoutCase;
     if soDown in Options then
-      SearchDown(buf,buf+SelStart+SelLength,Buf+(BufLen-1), SearchString, Equal, (soWholeWord in Options))
+      result := SearchDown(buf,buf+SelStart,Buf+(BufLen-1), SearchString, Equal, (soWholeWord in Options))
     else
-      SearchUp(buf,buf+SelStart+SelLength,Buf+(BufLen-1), SearchString, Equal, (soWholeWord in Options))
-    {$ifdef noexception}
+      result := SearchUp(buf,buf+SelStart,Buf+(Buflen-1), SearchString, Equal, (soWholeWord in Options));
     end;
-    {$endif}
 end;
 

+ 208 - 0
rtl/tests/tccollection.pp

@@ -0,0 +1,208 @@
+unit tccollection;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fpcunit, testutils, testregistry; 
+
+type
+
+  { TMyItem }
+
+  TMyItem = Class(TCollectionItem)
+  private
+    FNr: integer;
+  protected
+    // Expose
+    function GetOwner: TPersistent; override;
+  published
+    Property Nr : integer Read FNr Write FNr;
+  end;
+  
+  { TTestTCollection }
+
+  TTestTCollection= class(TTestCase)
+  private
+  protected
+    FColl : TCollection;
+    Function MyItem(I : integer) : TMyItem;
+    procedure AddItems(ACount : Integer);
+    procedure SetUp; override; 
+    procedure TearDown; override; 
+  published
+    procedure TestCreate;
+    procedure TestAdd;
+    procedure TestItemCollection;
+    procedure TestAddTwo;
+    Procedure TestDelete;
+    procedure TestClear;
+    Procedure TestFreeItem;
+    Procedure TestMoveForward;
+    Procedure TestMoveBackward;
+    Procedure TestID;
+    Procedure TestItemOwner;
+    Procedure TestDisplayName;
+    Procedure TestItemNamePath;
+  end;
+
+implementation
+
+procedure TTestTCollection.TestCreate;
+begin
+  AssertEquals('Item count 0 at create',0,FColl.Count);
+  AssertEquals('ItemClass is TMyItem',TMyItem,FColl.ItemClass);
+end;
+
+procedure TTestTCollection.TestAdd;
+begin
+  AddItems(1);
+  AssertEquals('Item count is 1 after add',1,FColl.Count);
+  AssertEquals('Item class is correct',FColl.ItemClass,FColl.Items[0].ClassType);
+  AssertEquals('Item index is 0',0,FColl.Items[0].Index);
+  AssertEquals('Item ID is 0',0,FColl.Items[0].Id);
+end;
+
+procedure TTestTCollection.TestItemCollection;
+begin
+  AddItems(1);
+  If MyItem(0).Collection<>FColl then
+    Fail('Item''s Collection is not collection');
+end;
+
+procedure TTestTCollection.TestAddTwo;
+
+Var
+  I: Integer;
+  
+begin
+  AddItems(3);
+  AssertEquals('Item count is 3 after add',3,FColl.Count);
+  For I:=0 to 2 do
+    begin
+    AssertEquals(Format('Item %d class is correct',[i]),FColl.ItemClass,FColl.Items[i].ClassType);
+    AssertEquals(Format('Item %d index is 0',[i]),i,FColl.Items[i].Index);
+    AssertEquals(Format('Item %d ID is 0',[i]),i,FColl.Items[i].Id);
+    AssertEquals(Format('Item %d ID is %d',[i,i+1]),i+1,MyItem(i).Nr);
+    end;
+end;
+
+procedure TTestTCollection.TestDelete;
+begin
+  AddItems(3);
+  FColl.Delete(1);
+  AssertEquals('Item count after delete',2,FColl.Count);
+  AssertEquals('Item 0 ok after delete',1,MyItem(0).Nr);
+  AssertEquals('Item 1 ok after delete',3,MyItem(1).Nr);
+end;
+
+procedure TTestTCollection.TestClear;
+begin
+  AddItems(3);
+  FColl.Clear;
+  AssertEquals('Item count after clear',0,FColl.Count);
+end;
+
+procedure TTestTCollection.TestFreeItem;
+begin
+  AddItems(3);
+  MyItem(1).Free;
+  AssertEquals('Item count after free',2,FColl.Count);
+  AssertEquals('Item 0 ok after free',1,MyItem(0).Nr);
+  AssertEquals('Item 1 ok after free',3,MyItem(1).Nr);
+end;
+
+procedure TTestTCollection.TestMoveForward;
+begin
+  AddItems(5);
+  MyItem(4).Index:=1;
+  AssertEquals('Item 0 ok after move',1,MyItem(0).Nr);
+  AssertEquals('Item 1 ok after move',5,MyItem(1).Nr);
+  AssertEquals('Item 2 ok after move',2,MyItem(2).Nr);
+  AssertEquals('Item 3 ok after move',3,MyItem(3).Nr);
+  AssertEquals('Item 4 ok after move',4,MyItem(4).Nr);
+end;
+
+procedure TTestTCollection.TestMoveBackward;
+
+begin
+  AddItems(5);
+  MyItem(1).Index:=3;
+  AssertEquals('Item 0 ok after move',1,MyItem(0).Nr);
+  AssertEquals('Item 1 ok after move',3,MyItem(1).Nr);
+  AssertEquals('Item 2 ok after move',4,MyItem(2).Nr);
+  AssertEquals('Item 3 ok after move',2,MyItem(3).Nr);
+  AssertEquals('Item 4 ok after move',5,MyItem(4).Nr);
+end;
+
+procedure TTestTCollection.TestID;
+
+Var
+  I : TMyItem;
+  
+begin
+  AddItems(5);
+  FColl.Delete(2);
+  FColl.Delete(2);
+  I:=TMyItem(FColl.Add);
+  AssertEquals('ID keeps counting up',5,I.Id)
+end;
+
+procedure TTestTCollection.TestItemOwner;
+begin
+  AddItems(1);
+  If (MyItem(0).GetOwner<>FColl) then
+    Fail('Item owner is not collection');
+end;
+
+procedure TTestTCollection.TestDisplayName;
+begin
+  AddItems(1);
+  AssertEquals('Displayname is classname','TMyItem',MyItem(0).DisplayName);
+end;
+
+procedure TTestTCollection.TestItemNamePath;
+begin
+  AddItems(2);
+  AssertEquals('Item namepath is collection namepath+index',FColl.GetNamePath+'[0]',MyItem(0).GetNamePath);
+  AssertEquals('Item namepath is collection namepath+index',FColl.GetNamePath+'[1]',MyItem(1).GetNamePath);
+end;
+
+function TTestTCollection.MyItem(I: integer): TMyItem;
+begin
+  Result:=TMyItem(FColl.Items[i]);
+end;
+
+procedure TTestTCollection.AddItems(ACount: Integer);
+
+Var
+  I : integer;
+  
+begin
+  For I:=1 to ACount do
+    TMyItem(FColl.Add).Nr:=I;
+end;
+
+procedure TTestTCollection.SetUp; 
+begin
+  FColl:=TCollection.Create(TMyItem);
+end; 
+
+procedure TTestTCollection.TearDown; 
+begin
+   FreeAndNil(FColl);
+end; 
+
+{ TMyItem }
+
+function TMyItem.GetOwner: TPersistent;
+begin
+  Result:=inherited GetOwner;
+end;
+
+initialization
+
+  RegisterTest(TTestTCollection); 
+end.
+

+ 398 - 0
rtl/tests/tclist.pp

@@ -0,0 +1,398 @@
+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.
+

+ 186 - 0
rtl/tests/tcpersistent.pp

@@ -0,0 +1,186 @@
+unit tcpersistent;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, fpcunit, testutils, testregistry; 
+
+type
+
+  { TTestTPersistent }
+
+  TTestTPersistent= class(TTestCase)
+  protected
+    Instance : TPersistent;
+    procedure SetUp; override; 
+    procedure TearDown; override; 
+  published
+    procedure TestPropCount;
+    procedure TestNamePath;
+  end; 
+  
+  { TMyPersistent }
+
+  TMyPersistent = Class(TPersistent)
+  private
+    FMyProp: Integer;
+    FOwner : TPersistent;
+  protected
+    function GetOwner: TPersistent; override;
+  public
+    procedure Assign(Source: TPersistent); virtual;
+  published
+    Property MyProp : Integer Read FMyProp Write FMyProp;
+  end;
+
+  { TTestPersistentDescendent }
+
+  TTestPersistentDescendent = class(TTestCase)
+  private
+    procedure WrongAssign;
+  Protected
+    Instance : TMyPersistent;
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    procedure TestPropCount;
+    procedure TestNamePath;
+    procedure TestNamePathWithOwner;
+    Procedure TestAssign;
+    Procedure TestAssignFail;
+  end;
+
+
+implementation
+
+uses typinfo;
+
+procedure TTestTPersistent.TestPropCount;
+
+Var
+  ACOunt : Integer;
+  P : Pointer;
+  
+begin
+  P:=Nil;
+  ACOunt:=GetPropList(Instance,P);
+  AssertEquals('Property count of TPersistence is zero',0,ACount);
+end;
+
+procedure TTestTPersistent.TestNamePath;
+begin
+  AssertEquals('Namepath is class name if there is no owner','TPersistent',Instance.GetNamePath);
+end;
+
+procedure TTestTPersistent.SetUp; 
+begin
+  Instance:=TPersistent.Create;
+end;
+
+procedure TTestTPersistent.TearDown; 
+begin
+  FreeAndNil(Instance);
+end; 
+
+{ TTestPersistentDescendent }
+
+procedure TTestPersistentDescendent.SetUp;
+begin
+  Instance:=TMyPersistent.Create;
+end;
+
+procedure TTestPersistentDescendent.TearDown;
+begin
+  FreeAndNil(Instance);
+end;
+
+procedure TTestPersistentDescendent.TestPropCount;
+
+Var
+  ACOunt : Integer;
+  P : Pointer;
+
+begin
+  P:=Nil;
+  ACount:=GetPropList(Instance,P);
+  AssertEquals('Property count of TPersistence is zero',1,ACount);
+end;
+
+procedure TTestPersistentDescendent.TestNamePath;
+begin
+  AssertEquals('Namepath is class name if there is no owner','TMyPersistent',Instance.GetNamePath);
+end;
+
+procedure TTestPersistentDescendent.TestNamePathWithOwner;
+
+Var
+  AOwner : TMyPersistent;
+  
+begin
+  AOwner:=TMyPersistent.Create;
+  try
+    Instance.FOwner:=AOwner;
+    AssertEquals('Namepath is owner namepath plus class name','TMyPersistent.TMyPersistent',Instance.GetNamePath);
+  finally
+    Aowner.Free;
+  end;
+end;
+
+procedure TTestPersistentDescendent.TestAssign;
+
+Var
+  I2 : TMyPersistent;
+  
+begin
+  I2:=TMyPersistent.Create;
+  try
+    I2.MyProp:=2;
+    Instance.Assign(I2);
+    AssertEquals('Property passed on during assign',2,Instance.MyProp);
+  finally
+    I2.Free;
+  end;
+end;
+
+
+procedure TTestPersistentDescendent.TestAssignFail;
+
+begin
+  AssertException('Assigning the wrong class',EConvertError,@WrongAssign);
+end;
+
+procedure TTestPersistentDescendent.WrongAssign;
+Var
+  I2 : TPersistent;
+
+begin
+  I2:=TPersistent.Create;
+  try
+    Instance.Assign(I2);
+  finally
+    I2.Free;
+  end;
+end;
+
+{ TMyPersistent }
+
+function TMyPersistent.GetOwner: TPersistent;
+begin
+  Result:=FOwner;
+end;
+
+procedure TMyPersistent.Assign(Source: TPersistent);
+begin
+  If (Source is TMyPersistent) then
+    FMyProp:=TMyPersistent(Source).FMyProp
+  else
+    Inherited;
+end;
+
+initialization
+
+  RegisterTests([TTestTPersistent,TTestPersistentDescendent]);
+end.
+

+ 189 - 0
rtl/tests/tcstringlist.pp

@@ -49,6 +49,27 @@ type
     Procedure TestSortedDupError;
     procedure TestSortedAddDuplicate;
     Procedure TestSortedIndexOf;
+    Procedure TestChange;
+    procedure TestChangeAgain;
+    procedure TestChangeCount;
+    procedure TestChangeClear;
+    Procedure TestSetText;
+    procedure TestSetTextEOL;
+    procedure TestSetTextEmpty;
+    procedure TestSetTextEOLEmpty;
+  end;
+
+  { TEventSink }
+
+  TEventSink = Class(TObject)
+  private
+    FCOunt: Integer;
+    FSender: TObject;
+  public
+    Procedure Change(Sender : TObject);
+    Procedure Reset;
+    Property ChangeCount : Integer Read FCOunt;
+    Property LastSender : TObject Read FSender;
   end;
 
 implementation
@@ -307,6 +328,160 @@ begin
   AssertEquals('Find third element, wrong case',4,List.IndexOf('ITEM 3'));
 end;
 
+procedure TTestTStringList.TestChange;
+
+Var
+  S : TEventSink;
+
+begin
+  S:=TEventSink.Create;
+  try
+    List.OnChange:[email protected];
+    List.Add('new');
+    AssertEquals('Change count equals 1 after add',1,S.ChangeCount);
+    If List<>S.LastSender then
+      Fail('Sender is list');
+  finally
+    S.Free;
+  end;
+end;
+
+procedure TTestTStringList.TestChangeAgain;
+
+Var
+  S : TEventSink;
+
+begin
+  S:=TEventSink.Create;
+  try
+    List.BeginUpdate;
+    Try
+    List.OnChange:[email protected];
+    List.Add('new');
+      AssertEquals('Change count equals 0 after add (beginupdate)',0,S.ChangeCount);
+      If (Nil<>S.LastSender) then
+        Fail('Sender is nil');
+    Finally
+      List.EndUpdate;
+    end;
+    AssertEquals('Change count equals 1 after add endupdate',1,S.ChangeCount);
+    If List<>S.LastSender then
+      Fail('Sender is list');
+  finally
+    S.Free;
+  end;
+end;
+
+procedure TTestTStringList.TestChangeCount;
+
+Var
+  S : TEventSink;
+
+begin
+  S:=TEventSink.Create;
+  try
+    List.BeginUpdate;
+    Try
+      // Count is 1, no notification
+      List.OnChange:[email protected];
+      List.Add('new');
+      AssertEquals('Change count equals 0 after add (1st beginupdate)',0,S.ChangeCount);
+      If (Nil<>S.LastSender) then
+        Fail('Sender is nil');
+      List.BeginUpdate;
+      Try
+        List.Add('new2');
+        // Count is 2, no notification
+        AssertEquals('Change count equals 0 after add (2nd beginupdate)',0,S.ChangeCount);
+        If (Nil<>S.LastSender) then
+          Fail('Sender is nil');
+      Finally
+        List.EndUpdate;
+      end;
+      // Count is 1 again, no notification
+      AssertEquals('Change count equals 0 after first endupdate',0,S.ChangeCount);
+      If (Nil<>S.LastSender) then
+        Fail('Sender is nil after first endupdate');
+    Finally
+      List.EndUpdate;
+    end;
+    AssertEquals('Change count equals 1 after add endupdate',1,S.ChangeCount);
+    If List<>S.LastSender then
+      Fail('Sender is list');
+  finally
+    S.Free;
+  end;
+end;
+
+procedure TTestTStringList.TestChangeClear;
+
+Var
+  S : TEventSink;
+  
+begin
+  FillList(9);
+  S:=TEventSink.Create;
+  try
+    List.OnChange:[email protected];
+    List.Clear;
+    AssertEquals('Change count equals 1 after clear',1,S.ChangeCount);
+  finally
+    S.Free;
+  end;
+end;
+
+procedure TTestTStringList.TestSetText;
+
+Const
+  Lines = 'Line 1'+sLineBreak+'Line 2'+sLineBreak+'Line 3';
+
+begin
+  List.Text:=Lines;
+  AssertEquals('3 lines set',3,List.Count);
+  AssertEquals('First line is "Line 1"','Line 1',List[0]);
+  AssertEquals('Second line is "Line 2"','Line 2',List[1]);
+  AssertEquals('Third line is "Line 3"','Line 3',List[2]);
+end;
+
+procedure TTestTStringList.TestSetTextEOL;
+
+Const
+  Lines = 'Line 1'+sLineBreak+'Line 2'+sLineBreak;
+
+begin
+  List.Text:=Lines;
+  AssertEquals('2 lines set',2,List.Count);
+  AssertEquals('First line is "Line 1"','Line 1',List[0]);
+  AssertEquals('Second line is "Line 2"','Line 2',List[1]);
+end;
+
+procedure TTestTStringList.TestSetTextEOLEmpty;
+
+Const
+  Lines = 'Line 1'+sLineBreak+'Line 2'+sLineBreak+slineBreak;
+
+begin
+  List.Text:=Lines;
+  AssertEquals('3 lines set',3,List.Count);
+  AssertEquals('First line is "Line 1"','Line 1',List[0]);
+  AssertEquals('Second line is "Line 2"','Line 2',List[1]);
+  AssertEquals('Third line is empty','',List[2]);
+end;
+
+procedure TTestTStringList.TestSetTextEmpty;
+
+Const
+  Lines = 'Line 1'+sLineBreak+sLineBreak+SlineBreak+'Line 2';
+
+begin
+  List.Text:=Lines;
+  AssertEquals('4 lines set',4,List.Count);
+  AssertEquals('First line is "Line 1"','Line 1',List[0]);
+  AssertEquals('Second line is empty','',List[1]);
+  AssertEquals('Third line is empty','',List[2]);
+  AssertEquals('Fourth line is "Line 2"','Line 2',List[3]);
+end;
+
 
 procedure TTestTStringList.FillList(ACount: Integer);
 
@@ -328,6 +503,20 @@ begin
   FreeAndNil(List);
 end;
 
+{ TEventSink }
+
+procedure TEventSink.Change(Sender: TObject);
+begin
+  Inc(FCount);
+  FSender:=Sender;
+end;
+
+procedure TEventSink.Reset;
+begin
+  FCount:=0;
+  FSender:=Nil;
+end;
+
 initialization
   RegisterTest(TTestTStringList);
 end.

+ 50 - 2
rtl/tests/tcstrutils.pp

@@ -5,7 +5,7 @@ unit tcstrutils;
 interface
 
 uses
-  Classes, SysUtils, fpcunit, testutils, testregistry, strutils;
+  Classes, SysUtils, fpcunit, testregistry, strutils;
 
 type
 
@@ -31,6 +31,13 @@ type
     procedure TestSimplePartialStart;
     procedure TestEndMatchDown;
     procedure TestEndMatch;
+    procedure TestWholeWordAtStart;
+    procedure TestWholeWordAtStartDown;
+    procedure TestWholeWordAtEnd;
+    procedure TestWholeWordAtEndDown;
+    procedure TestEmptySearchString;
+    procedure TestSelstartBeforeBuf;
+    procedure testSelstartAfterBuf;
   end;
 
 implementation
@@ -41,11 +48,15 @@ Const
    //  1234567890123456789012345678901234567890123456789
   S = 'Some very long string with some words in it';
   SLen = Length(S);
-  Starts : Array[1..3] of Integer = (0,10,41);
   
 {$define usenew}
 {$ifdef usenew}
 {$i searchbuf.inc}
+const
+  WhichSearchbuf = 'new';
+{$else}
+const
+  WhichSearchbuf = 'old';
 {$endif}
 
 procedure TTestSearchBuf.TestSearch(Sub: String; Start: Integer;
@@ -111,6 +122,41 @@ begin
   TestSearch('it',SLen,[],42);
 end;
 
+procedure TTestSearchBuf.TestWholeWordAtStart;
+begin
+  TestSearch('Some',20,[soWholeWord],1);
+end;
+
+procedure TTestSearchBuf.TestWholeWordAtStartDown;
+begin
+  TestSearch('Some',0,[soDown,soWholeWord],1);
+end;
+
+procedure TTestSearchBuf.TestWholeWordAtEnd;
+begin
+  TestSearch('it',SLen,[soWholeWord],42);
+end;
+
+procedure TTestSearchBuf.TestWholeWordAtEndDown;
+begin
+  TestSearch('it',30,[soDown,soWholeWord],42);
+end;
+
+procedure TTestSearchBuf.TestEmptySearchString;
+begin
+  TestSearch('',30,[],-1);
+end;
+
+procedure TTestSearchBuf.TestSelstartBeforeBuf;
+begin
+  TestSearch('very',-5,[soDown],-1);
+end;
+
+procedure TTestSearchBuf.testSelstartAfterBuf;
+begin
+  TestSearch('very',100,[],-1);
+end;
+
 procedure TTestSearchBuf.TestSimpleDownPos;
 begin
   TestSearch('it',30,[soDown],42);
@@ -153,5 +199,7 @@ end;
 
 initialization
   RegisterTest(TTestSearchBuf);
+  writeln ('Testing with ', WhichSearchbuf, ' implementation');
+  writeln;
 end.
 

+ 105 - 0
rtl/tests/testclasses.lpi

@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <PathDelim Value="/"/>
+    <Version Value="6"/>
+    <General>
+      <MainUnit Value="0"/>
+      <IconPath Value="./"/>
+      <TargetFileExt Value=""/>
+      <Title Value="findnested"/>
+      <ActiveEditorIndexAtStart Value="0"/>
+    </General>
+    <VersionInfo>
+      <ProjectVersion Value=""/>
+      <Language Value=""/>
+      <CharSet Value=""/>
+    </VersionInfo>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IgnoreBinaries Value="False"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="2">
+      <Item1>
+        <PackageName Value="FCL"/>
+      </Item1>
+      <Item2>
+        <PackageName Value="FPCUnitConsoleRunner"/>
+      </Item2>
+    </RequiredPackages>
+    <Units Count="6">
+      <Unit0>
+        <Filename Value="testclasses.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="testclasses"/>
+        <UsageCount Value="20"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="tcfindnested.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tcfindnested"/>
+        <CursorPos X="1" Y="91"/>
+        <TopLine Value="61"/>
+        <EditorIndex Value="0"/>
+        <UsageCount Value="20"/>
+        <Loaded Value="True"/>
+      </Unit1>
+      <Unit2>
+        <Filename Value="tcstringlist.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tcstringlist"/>
+        <UsageCount Value="20"/>
+        <SyntaxHighlighter Value="Text"/>
+      </Unit2>
+      <Unit3>
+        <Filename Value="tccollection.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tccollection"/>
+        <UsageCount Value="20"/>
+        <SyntaxHighlighter Value="Text"/>
+      </Unit3>
+      <Unit4>
+        <Filename Value="tclist.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tclist"/>
+        <UsageCount Value="20"/>
+        <SyntaxHighlighter Value="Text"/>
+      </Unit4>
+      <Unit5>
+        <Filename Value="tcpersistent.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tcpersistent"/>
+        <UsageCount Value="20"/>
+        <SyntaxHighlighter Value="Text"/>
+      </Unit5>
+    </Units>
+    <JumpHistory Count="0" HistoryIndex="-1"/>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="5"/>
+    <CodeGeneration>
+      <Generate Value="Faster"/>
+    </CodeGeneration>
+    <Other>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="2">
+      <Item1>
+        <Name Value="ECodetoolError"/>
+      </Item1>
+      <Item2>
+        <Name Value="EFOpenError"/>
+      </Item2>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 3 - 2
rtl/tests/findnested.lpr → rtl/tests/testclasses.lpr

@@ -1,9 +1,10 @@
-program findnested;
+program testclasses;
 
 {$mode objfpc}{$H+}
 
 uses
-  Classes, consoletestrunner, tcfindnested;
+  Classes, consoletestrunner, tcfindnested, tcstringlist, tccollection, tclist,
+  tcpersistent;
 
 type
 

+ 98 - 64
rtl/tests/tstrutils.lpi

@@ -5,8 +5,9 @@
     <Version Value="6"/>
     <General>
       <MainUnit Value="0"/>
+      <IconPath Value="./"/>
       <TargetFileExt Value=""/>
-      <ActiveEditorIndexAtStart Value="1"/>
+      <ActiveEditorIndexAtStart Value="2"/>
     </General>
     <VersionInfo>
       <ProjectVersion Value=""/>
@@ -34,35 +35,35 @@
         <PackageName Value="FCL"/>
       </Item2>
     </RequiredPackages>
-    <Units Count="6">
+    <Units Count="10">
       <Unit0>
         <Filename Value="tstrutils.lpr"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="tstrutils"/>
-        <CursorPos X="1" Y="21"/>
+        <CursorPos X="63" Y="6"/>
         <TopLine Value="1"/>
-        <EditorIndex Value="4"/>
-        <UsageCount Value="20"/>
+        <EditorIndex Value="7"/>
+        <UsageCount Value="44"/>
         <Loaded Value="True"/>
       </Unit0>
       <Unit1>
         <Filename Value="tcstrutils.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="tcstrutils"/>
-        <CursorPos X="10" Y="52"/>
+        <CursorPos X="1" Y="1"/>
         <TopLine Value="1"/>
         <EditorIndex Value="0"/>
-        <UsageCount Value="20"/>
+        <UsageCount Value="44"/>
         <Loaded Value="True"/>
       </Unit1>
       <Unit2>
         <Filename Value="tcstringlist.pp"/>
         <IsPartOfProject Value="True"/>
         <UnitName Value="tcstringlist"/>
-        <CursorPos X="1" Y="2"/>
+        <CursorPos X="19" Y="47"/>
         <TopLine Value="1"/>
-        <EditorIndex Value="2"/>
-        <UsageCount Value="20"/>
+        <EditorIndex Value="1"/>
+        <UsageCount Value="44"/>
         <Loaded Value="True"/>
       </Unit2>
       <Unit3>
@@ -70,145 +71,178 @@
         <UnitName Value="fpcunit"/>
         <CursorPos X="6" Y="554"/>
         <TopLine Value="524"/>
-        <UsageCount Value="10"/>
+        <UsageCount Value="8"/>
       </Unit3>
       <Unit4>
         <Filename Value="../../../../fpc/rtl/objpas/classes/classesh.inc"/>
-        <CursorPos X="3" Y="66"/>
-        <TopLine Value="40"/>
-        <EditorIndex Value="3"/>
-        <UsageCount Value="10"/>
+        <CursorPos X="1" Y="233"/>
+        <TopLine Value="212"/>
+        <EditorIndex Value="4"/>
+        <UsageCount Value="22"/>
         <Loaded Value="True"/>
       </Unit4>
       <Unit5>
         <Filename Value="searchbuf.inc"/>
-        <CursorPos X="15" Y="112"/>
+        <CursorPos X="47" Y="117"/>
         <TopLine Value="65"/>
-        <EditorIndex Value="1"/>
-        <UsageCount Value="10"/>
-        <Loaded Value="True"/>
+        <UsageCount Value="8"/>
       </Unit5>
+      <Unit6>
+        <Filename Value="tclist.pp"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="tclist"/>
+        <CursorPos X="66" Y="341"/>
+        <TopLine Value="346"/>
+        <EditorIndex Value="3"/>
+        <UsageCount Value="44"/>
+        <Loaded Value="True"/>
+      </Unit6>
+      <Unit7>
+        <Filename Value="../../../../fpc/rtl/objpas/classes/resreference.inc"/>
+        <CursorPos X="39" Y="345"/>
+        <TopLine Value="311"/>
+        <EditorIndex Value="6"/>
+        <UsageCount Value="21"/>
+        <Loaded Value="True"/>
+      </Unit7>
+      <Unit8>
+        <Filename Value="../../../../fpc/rtl/objpas/classes/lists.inc"/>
+        <CursorPos X="20" Y="271"/>
+        <TopLine Value="222"/>
+        <EditorIndex Value="5"/>
+        <UsageCount Value="21"/>
+        <Loaded Value="True"/>
+      </Unit8>
+      <Unit9>
+        <Filename Value="testll.pp"/>
+        <UnitName Value="Testll"/>
+        <CursorPos X="1" Y="1"/>
+        <TopLine Value="1"/>
+        <EditorIndex Value="2"/>
+        <UsageCount Value="20"/>
+        <Loaded Value="True"/>
+      </Unit9>
     </Units>
     <JumpHistory Count="30" HistoryIndex="29">
       <Position1>
-        <Filename Value="tcstringlist.pp"/>
-        <Caret Line="200" Column="15" TopLine="176"/>
+        <Filename Value="tclist.pp"/>
+        <Caret Line="183" Column="30" TopLine="157"/>
       </Position1>
       <Position2>
-        <Filename Value="tcstringlist.pp"/>
-        <Caret Line="207" Column="40" TopLine="181"/>
+        <Filename Value="tclist.pp"/>
+        <Caret Line="342" Column="18" TopLine="327"/>
       </Position2>
       <Position3>
-        <Filename Value="tcstringlist.pp"/>
-        <Caret Line="43" Column="1" TopLine="16"/>
+        <Filename Value="tclist.pp"/>
+        <Caret Line="357" Column="5" TopLine="300"/>
       </Position3>
       <Position4>
-        <Filename Value="tcstringlist.pp"/>
-        <Caret Line="215" Column="5" TopLine="158"/>
+        <Filename Value="tclist.pp"/>
+        <Caret Line="354" Column="13" TopLine="333"/>
       </Position4>
       <Position5>
-        <Filename Value="tcstringlist.pp"/>
-        <Caret Line="216" Column="8" TopLine="189"/>
+        <Filename Value="tclist.pp"/>
+        <Caret Line="365" Column="1" TopLine="328"/>
       </Position5>
       <Position6>
-        <Filename Value="tcstringlist.pp"/>
-        <Caret Line="55" Column="1" TopLine="27"/>
+        <Filename Value="tclist.pp"/>
+        <Caret Line="360" Column="42" TopLine="334"/>
       </Position6>
       <Position7>
-        <Filename Value="tcstringlist.pp"/>
-        <Caret Line="242" Column="1" TopLine="191"/>
+        <Filename Value="tclist.pp"/>
+        <Caret Line="357" Column="7" TopLine="335"/>
       </Position7>
       <Position8>
-        <Filename Value="tcstringlist.pp"/>
-        <Caret Line="65" Column="54" TopLine="27"/>
+        <Filename Value="tclist.pp"/>
+        <Caret Line="366" Column="20" TopLine="340"/>
       </Position8>
       <Position9>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="224" Column="1" TopLine="199"/>
+        <Caret Line="52" Column="26" TopLine="27"/>
       </Position9>
       <Position10>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="233" Column="5" TopLine="176"/>
+        <Caret Line="58" Column="49" TopLine="31"/>
       </Position10>
       <Position11>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="16" Column="3" TopLine="15"/>
+        <Caret Line="57" Column="3" TopLine="55"/>
       </Position11>
       <Position12>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="78" Column="25" TopLine="51"/>
+        <Caret Line="60" Column="22" TopLine="36"/>
       </Position12>
       <Position13>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="26" Column="38" TopLine="25"/>
+        <Caret Line="327" Column="5" TopLine="270"/>
       </Position13>
       <Position14>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="258" Column="82" TopLine="232"/>
+        <Caret Line="334" Column="1" TopLine="315"/>
       </Position14>
       <Position15>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="254" Column="13" TopLine="228"/>
+        <Caret Line="62" Column="9" TopLine="36"/>
       </Position15>
       <Position16>
-        <Filename Value="../../../../fpc/rtl/objpas/classes/classesh.inc"/>
-        <Caret Line="618" Column="36" TopLine="592"/>
+        <Filename Value="tcstringlist.pp"/>
+        <Caret Line="332" Column="29" TopLine="301"/>
       </Position16>
       <Position17>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="114" Column="5" TopLine="57"/>
+        <Caret Line="335" Column="46" TopLine="308"/>
       </Position17>
       <Position18>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="115" Column="69" TopLine="107"/>
+        <Caret Line="330" Column="3" TopLine="324"/>
       </Position18>
       <Position19>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="274" Column="5" TopLine="217"/>
+        <Caret Line="335" Column="52" TopLine="309"/>
       </Position19>
       <Position20>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="280" Column="1" TopLine="247"/>
+        <Caret Line="334" Column="1" TopLine="309"/>
       </Position20>
       <Position21>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="239" Column="5" TopLine="182"/>
+        <Caret Line="360" Column="1" TopLine="319"/>
       </Position21>
       <Position22>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="240" Column="20" TopLine="217"/>
+        <Caret Line="26" Column="27" TopLine="25"/>
       </Position22>
       <Position23>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="253" Column="15" TopLine="237"/>
+        <Caret Line="373" Column="5" TopLine="316"/>
       </Position23>
       <Position24>
         <Filename Value="tcstringlist.pp"/>
-        <Caret Line="272" Column="1" TopLine="272"/>
+        <Caret Line="330" Column="5" TopLine="325"/>
       </Position24>
       <Position25>
-        <Filename Value="searchbuf.inc"/>
-        <Caret Line="1" Column="1" TopLine="1"/>
+        <Filename Value="tcstringlist.pp"/>
+        <Caret Line="420" Column="1" TopLine="399"/>
       </Position25>
       <Position26>
-        <Filename Value="searchbuf.inc"/>
-        <Caret Line="40" Column="21" TopLine="12"/>
+        <Filename Value="tcstringlist.pp"/>
+        <Caret Line="331" Column="5" TopLine="326"/>
       </Position26>
       <Position27>
-        <Filename Value="searchbuf.inc"/>
-        <Caret Line="56" Column="9" TopLine="31"/>
+        <Filename Value="tcstringlist.pp"/>
+        <Caret Line="440" Column="1" TopLine="420"/>
       </Position27>
       <Position28>
-        <Filename Value="searchbuf.inc"/>
-        <Caret Line="75" Column="21" TopLine="49"/>
+        <Filename Value="tcstringlist.pp"/>
+        <Caret Line="26" Column="30" TopLine="25"/>
       </Position28>
       <Position29>
-        <Filename Value="searchbuf.inc"/>
-        <Caret Line="65" Column="42" TopLine="39"/>
+        <Filename Value="tcstringlist.pp"/>
+        <Caret Line="467" Column="1" TopLine="432"/>
       </Position29>
       <Position30>
-        <Filename Value="searchbuf.inc"/>
-        <Caret Line="110" Column="94" TopLine="65"/>
+        <Filename Value="tcstringlist.pp"/>
+        <Caret Line="26" Column="35" TopLine="25"/>
       </Position30>
     </JumpHistory>
   </ProjectOptions>

+ 1 - 1
rtl/tests/tstrutils.lpr

@@ -3,7 +3,7 @@ program tstrutils;
 {$mode objfpc}{$H+}
 
 uses
-  Classes, consoletestrunner, tcstrutils, tcstringlist;
+  Classes, consoletestrunner, tcstrutils, tcstringlist, tclist;
 
 type