123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536 |
- {
- This file is part of the Free Pascal/NewPascal run time library.
- Copyright (c) 2014 by Maciej Izak (hnb)
- member of the NewPascal development team (http://newpascal.org)
- Copyright(c) 2004-2018 DaThoX
- It contains tests for the Free Pascal generics library
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- unit tests.generics.utils;
- {$mode delphi}
- interface
- uses
- fpcunit, testutils, testregistry,
- Classes, SysUtils, Generics.Collections;
- type
- TNotificationRec<T> = record
- Sender: TObject;
- Item: T;
- Action: TCollectionNotification;
- Executed: boolean;
- end;
- TNotificationNodeRec<TValue, TInfo> = record
- Sender: TObject;
- Key: string;
- Value: TValue;
- IgnoreNodePtr: boolean;
- Node: TCustomAVLTreeMap<string, TValue, TInfo>.PNode;
- Action: TCollectionNotification;
- Dispose: boolean;
- Executed: boolean;
- end;
- TTestCollections = class(TTestCase)
- private type
- TNotificationRec_String = TNotificationRec<string>;
- TNotificationRec_TObject = TNotificationRec<TObject>;
- TNotificationNodeRec_String = TNotificationNodeRec<string, TEmptyRecord>;
- TNotificationNodeRec_Empty = TNotificationNodeRec<TEmptyRecord, TEmptyRecord>;
- PNode_String = TCustomAVLTreeMap<string, string, TEmptyRecord>.PNode;
- PNode_Empty = TCustomAVLTreeMap<string, TEmptyRecord, TEmptyRecord>.PNode;
- private
- NotificationsListNode_String: TList<TNotificationNodeRec_String>;
- NotificationsListNode_Empty: TList<TNotificationNodeRec_Empty>;
- NotificationsListStr: TList<TNotificationRec_String>;
- NotificationsListObj: TList<TNotificationRec_TObject>;
- NotificationsIndex, NotificationsNodesIndex: Integer;
- protected
- procedure NotificationAdd(ASender: TObject; const AKey, AValue: string; ANode: PNode_String;
- AAction: TCollectionNotification; ADispose, AIgnoreNodePtr: boolean); overload;
- procedure NotificationAdd(ASender: TObject; const AKeys, AValues: array of string;
- const ANodes: array of PNode_String; AAction: TCollectionNotification; ADispose, AIgnoreNodePtr: boolean); overload;
- procedure NotificationAdd(ASender: TObject; const AKey: string; ANode: PNode_Empty;
- AAction: TCollectionNotification; ADispose, AIgnoreNodePtr: boolean); overload;
- procedure NotificationAdd(ASender: TObject; const AKeys: array of string;
- const ANodes: array of PNode_Empty; AAction: TCollectionNotification; ADispose, AIgnoreNodePtr: boolean); overload;
- procedure NotificationAdd(ASender: TObject; const AItem: string;
- AAction: TCollectionNotification); overload;
- procedure NotificationAdd(ASender: TObject; const AItems: array of string;
- AAction: TCollectionNotification); overload;
- procedure NotificationAdd(ASender: TObject; const AItem: TObject;
- AAction: TCollectionNotification); overload;
- procedure NotificationAdd(ASender: TObject; const AItems: array of TObject;
- AAction: TCollectionNotification); overload;
- procedure AssertNotificationsExecutedNodeStr;
- procedure ClearNotificationsNodeStr;
- procedure AssertNotificationsExecutedNodeEmpty;
- procedure ClearNotificationsNodeEmpty;
- procedure AssertNotificationsExecutedStr;
- procedure ClearNotificationsStr;
- procedure AssertNotificationsExecutedObj;
- procedure ClearNotificationsObj;
- procedure NotifyTestNodeStr(ASender: TObject; ANode: PNode_String; AAction: TCollectionNotification; ADispose: boolean);
- procedure NotifyTestNodeEmpty(ASender: TObject; ANode: PNode_Empty; AAction: TCollectionNotification; ADispose: boolean);
- procedure NotifyTestStr(ASender: TObject; const AItem: string; AAction: TCollectionNotification);
- procedure NotifyTestObj(ASender: TObject; const AItem: TObject; AAction: TCollectionNotification);
- procedure CreateObjects(var AArray: TArray<TObject>; ACount: Integer);
- procedure FreeObjects(AArray: TArray<TObject>);
- public
- constructor Create; override;
- destructor Destroy; override;
- end;
- TStringList = TList<string>;
- { TStringsEnumerator }
- TStringsEnumerator = class(TInterfacedObject, IEnumerator<string>)
- private
- FEnumerator: TStringList.TEnumerator;
- FCollection: TStringList;
- function GetCurrent: string;
- function MoveNext: Boolean;
- procedure Reset;
- property Current: string read GetCurrent;
- constructor Create(AEnumerator: TStringList.TEnumerator; ACollection: TStringList);
- destructor Destroy; override;
- end;
- { TStringsEnumerable }
- TStringsEnumerable = class(TInterfacedObject, IEnumerable<string>)
- private
- FEnumerable: TStringList;
- function GetEnumerator: IEnumerator<string>;
- constructor Create(const AItems: array of string);
- end;
- TObjectList = TList<TObject>;
- { TObjectEnumerator }
- TObjectEnumerator = class(TInterfacedObject, IEnumerator<TObject>)
- private
- FEnumerator: TObjectList.TEnumerator;
- FCollection: TObjectList;
- function GetCurrent: TObject;
- function MoveNext: Boolean;
- procedure Reset;
- property Current: TObject read GetCurrent;
- constructor Create(AEnumerator: TObjectList.TEnumerator; ACollection: TObjectList);
- destructor Destroy; override;
- end;
- { TObjectEnumerable }
- TObjectEnumerable = class(TInterfacedObject, IEnumerable<TObject>)
- private
- FEnumerable: TObjectList;
- function GetEnumerator: IEnumerator<TObject>;
- constructor Create(const AItems: array of TObject);
- end;
- function EnumerableStringsIntf(const AItems: array of string): IEnumerable<string>;
- function EnumerableStringsObj(const AItems: array of string): TEnumerable<string>;
- function EnumerableObjectsIntf(const AItems: array of TObject): IEnumerable<TObject>;
- function EnumerableObjectsObj(const AItems: array of TObject): TEnumerable<TObject>;
- implementation
- function EnumerableStringsIntf(const AItems: array of string): IEnumerable<string>;
- begin
- Result := TStringsEnumerable.Create(AItems);
- end;
- function EnumerableStringsObj(const AItems: array of string): TEnumerable<string>;
- begin
- Result := TStringList.Create;
- TStringList(Result).AddRange(AItems);
- end;
- function EnumerableObjectsIntf(const AItems: array of TObject): IEnumerable<TObject>;
- begin
- Result := TObjectEnumerable.Create(AItems);
- end;
- function EnumerableObjectsObj(const AItems: array of TObject): TEnumerable<TObject>;
- begin
- Result := TObjectList.Create;
- TObjectList(Result).AddRange(AItems);
- end;
- { TTestCollections }
- procedure TTestCollections.NotificationAdd(ASender: TObject;
- const AKey, AValue: string; ANode: PNode_String; AAction: TCollectionNotification; ADispose, AIgnoreNodePtr: boolean);
- var
- LNotification: TNotificationNodeRec_String;
- begin
- LNotification.Sender := ASender;
- LNotification.Key := AKey;
- LNotification.Value := AValue;
- LNotification.IgnoreNodePtr := AIgnoreNodePtr;
- LNotification.Node := ANode;
- LNotification.Action := AAction;
- LNotification.Dispose := ADispose;
- LNotification.Executed := False;
- NotificationsListNode_String.Add(LNotification);
- end;
- procedure TTestCollections.NotificationAdd(ASender: TObject;
- const AKeys, AValues: array of string; const ANodes: array of PNode_String; AAction: TCollectionNotification; ADispose, AIgnoreNodePtr: boolean);
- var
- i: Integer;
- begin
- Assert(Length(AKeys) = Length(ANodes));
- for i := 0 to High(AKeys) do
- NotificationAdd(ASender, AKeys[i], AValues[i], ANodes[i], AAction, ADispose, AIgnoreNodePtr);
- end;
- procedure TTestCollections.NotificationAdd(ASender: TObject;
- const AKey: string; ANode: PNode_Empty; AAction: TCollectionNotification; ADispose, AIgnoreNodePtr: boolean);
- var
- LNotification: TNotificationNodeRec_Empty;
- begin
- LNotification.Sender := ASender;
- LNotification.Key := AKey;
- LNotification.Value := EmptyRecord;
- LNotification.IgnoreNodePtr := AIgnoreNodePtr;
- LNotification.Node := ANode;
- LNotification.Action := AAction;
- LNotification.Dispose := ADispose;
- LNotification.Executed := False;
- NotificationsListNode_Empty.Add(LNotification);
- end;
- procedure TTestCollections.NotificationAdd(ASender: TObject;
- const AKeys: array of string; const ANodes: array of PNode_Empty; AAction: TCollectionNotification; ADispose, AIgnoreNodePtr: boolean);
- var
- i: Integer;
- begin
- Assert(Length(AKeys) = Length(ANodes));
- for i := 0 to High(AKeys) do
- NotificationAdd(ASender, AKeys[i], ANodes[i], AAction, ADispose, AIgnoreNodePtr);
- end;
- procedure TTestCollections.NotificationAdd(ASender: TObject;
- const AItem: string; AAction: TCollectionNotification);
- var
- LNotification: TNotificationRec_String;
- begin
- LNotification.Sender := ASender;
- LNotification.Item := AItem;
- LNotification.Action := AAction;
- LNotification.Executed := False;
- NotificationsListStr.Add(LNotification);
- end;
- procedure TTestCollections.NotificationAdd(ASender: TObject;
- const AItems: array of string; AAction: TCollectionNotification);
- var
- s: string;
- begin
- for s in AItems do
- NotificationAdd(ASender, s, AAction);
- end;
- procedure TTestCollections.NotificationAdd(ASender: TObject;
- const AItem: TObject; AAction: TCollectionNotification);
- var
- LNotification: TNotificationRec_TObject;
- begin
- LNotification.Sender := ASender;
- LNotification.Item := AItem;
- LNotification.Action := AAction;
- LNotification.Executed := False;
- NotificationsListObj.Add(LNotification);
- end;
- procedure TTestCollections.NotificationAdd(ASender: TObject;
- const AItems: array of TObject; AAction: TCollectionNotification);
- var
- o: TObject;
- begin
- for o in AItems do
- NotificationAdd(ASender, o, AAction);
- end;
- procedure TTestCollections.AssertNotificationsExecutedNodeStr;
- var
- p: ^TNotificationNodeRec_String;
- begin
- for p in NotificationsListNode_String.Ptr^ do
- AssertTrue(p^.Executed);
- AssertEquals(NotificationsNodesIndex, NotificationsListNode_String.Count);
- ClearNotificationsStr;
- end;
- procedure TTestCollections.ClearNotificationsNodeStr;
- begin
- NotificationsListNode_String.Clear;
- NotificationsNodesIndex := 0;
- end;
- procedure TTestCollections.AssertNotificationsExecutedNodeEmpty;
- var
- p: ^TNotificationNodeRec_Empty;
- begin
- for p in NotificationsListNode_Empty.Ptr^ do
- AssertTrue(p^.Executed);
- AssertEquals(NotificationsNodesIndex, NotificationsListNode_Empty.Count);
- ClearNotificationsStr;
- end;
- procedure TTestCollections.ClearNotificationsNodeEmpty;
- begin
- NotificationsListNode_Empty.Clear;
- NotificationsNodesIndex := 0;
- end;
- procedure TTestCollections.AssertNotificationsExecutedStr;
- var
- p: ^TNotificationRec_String;
- begin
- for p in NotificationsListStr.Ptr^ do
- AssertTrue(p^.Executed);
- AssertEquals(NotificationsIndex, NotificationsListStr.Count);
- ClearNotificationsStr;
- end;
- procedure TTestCollections.ClearNotificationsStr;
- begin
- NotificationsListStr.Clear;
- NotificationsIndex := 0;
- end;
- procedure TTestCollections.AssertNotificationsExecutedObj;
- var
- p: ^TNotificationRec_TObject;
- begin
- for p in NotificationsListObj.Ptr^ do
- AssertTrue(p^.Executed);
- AssertEquals(NotificationsIndex, NotificationsListObj.Count);
- ClearNotificationsObj;
- end;
- procedure TTestCollections.ClearNotificationsObj;
- begin
- NotificationsListObj.Clear;
- NotificationsIndex := 0;
- end;
- procedure TTestCollections.NotifyTestNodeStr(ASender: TObject; ANode: PNode_String; AAction: TCollectionNotification; ADispose: boolean);
- var
- LNotification: TNotificationNodeRec_String;
- begin
- AssertTrue(NotificationsNodesIndex < NotificationsListNode_String.Count);
- LNotification := NotificationsListNode_String[NotificationsNodesIndex];
- AssertTrue(ASender = LNotification.Sender);
- AssertEquals(ANode.Key, LNotification.Key);
- AssertEquals(ANode.Value, LNotification.Value);
- if not LNotification.IgnoreNodePtr then
- AssertSame(ANode, LNotification.Node);
- AssertTrue(AAction = LNotification.Action);
- AssertEquals(ADispose, LNotification.Dispose);
- AssertFalse(LNotification.Executed);
- LNotification.Executed := True;
- NotificationsListNode_String[NotificationsNodesIndex] := LNotification;
- Inc(NotificationsNodesIndex)
- end;
- procedure TTestCollections.NotifyTestNodeEmpty(ASender: TObject; ANode: PNode_Empty; AAction: TCollectionNotification; ADispose: boolean);
- var
- LNotification: TNotificationNodeRec_Empty;
- begin
- AssertTrue(NotificationsNodesIndex < NotificationsListNode_Empty.Count);
- LNotification := NotificationsListNode_Empty[NotificationsNodesIndex];
- AssertTrue(ASender = LNotification.Sender);
- AssertEquals(ANode.Key, LNotification.Key);
- if not LNotification.IgnoreNodePtr then
- AssertSame(ANode, LNotification.Node);
- AssertTrue(AAction = LNotification.Action);
- AssertEquals(ADispose, LNotification.Dispose);
- AssertFalse(LNotification.Executed);
- LNotification.Executed := True;
- NotificationsListNode_Empty[NotificationsNodesIndex] := LNotification;
- Inc(NotificationsNodesIndex)
- end;
- procedure TTestCollections.NotifyTestStr(ASender: TObject; const AItem: string; AAction: TCollectionNotification);
- var
- LNotification: TNotificationRec_String;
- begin
- AssertTrue(NotificationsIndex < NotificationsListStr.Count);
- LNotification := NotificationsListStr[NotificationsIndex];
- AssertTrue(ASender = LNotification.Sender);
- AssertEquals(AItem, LNotification.Item);
- AssertTrue(AAction = LNotification.Action);
- AssertFalse(LNotification.Executed);
- LNotification.Executed := True;
- NotificationsListStr[NotificationsIndex] := LNotification;
- Inc(NotificationsIndex)
- end;
- procedure TTestCollections.NotifyTestObj(ASender: TObject; const AItem: TObject; AAction: TCollectionNotification);
- var
- LNotification: TNotificationRec_TObject;
- begin
- AssertTrue(NotificationsIndex < NotificationsListObj.Count);
- LNotification := NotificationsListObj[NotificationsIndex];
- AssertTrue(ASender = LNotification.Sender);
- AssertTrue(AItem = LNotification.Item);
- AssertTrue(AAction = LNotification.Action);
- AssertFalse(LNotification.Executed);
- LNotification.Executed := True;
- NotificationsListObj[NotificationsIndex] := LNotification;
- Inc(NotificationsIndex)
- end;
- procedure TTestCollections.CreateObjects(var AArray: TArray<TObject>; ACount: Integer);
- var
- i: Integer;
- begin
- SetLength(AArray, ACount);
- for i := 0 to ACount - 1 do
- AArray[i] := TObject.Create;
- end;
- procedure TTestCollections.FreeObjects(AArray: TArray<TObject>);
- var
- o: TObject;
- begin
- for o in AArray do
- o.Free;
- end;
- constructor TTestCollections.Create;
- begin
- inherited;
- NotificationsListStr := TList<TNotificationRec_String>.Create;
- NotificationsListObj := TList<TNotificationRec_TObject>.Create;
- NotificationsListNode_String := TList<TNotificationNodeRec_String>.Create;
- NotificationsListNode_Empty := TList<TNotificationNodeRec_Empty>.Create;
- end;
- destructor TTestCollections.Destroy;
- begin
- NotificationsListNode_Empty.Free;
- NotificationsListNode_String.Free;
- NotificationsListObj.Free;
- NotificationsListStr.Free;
- inherited;
- end;
- { TStringsEnumerable }
- function TStringsEnumerable.GetEnumerator: IEnumerator<string>;
- begin
- Result := TStringsEnumerator.Create(FEnumerable.GetEnumerator, FEnumerable);
- end;
- constructor TStringsEnumerable.Create(const AItems: array of string);
- begin
- FEnumerable := TStringList.Create;
- FEnumerable.AddRange(AItems);
- end;
- { TStringsEnumerator }
- function TStringsEnumerator.GetCurrent: string;
- begin
- Result := FEnumerator.Current;
- end;
- function TStringsEnumerator.MoveNext: Boolean;
- begin
- Result := FEnumerator.MoveNext;
- end;
- procedure TStringsEnumerator.Reset;
- begin
- FEnumerator.Free;
- FEnumerator := FCollection.GetEnumerator;
- end;
- constructor TStringsEnumerator.Create(AEnumerator: TStringList.TEnumerator; ACollection: TStringList);
- begin
- FEnumerator := AEnumerator;
- FCollection := ACollection;
- end;
- destructor TStringsEnumerator.Destroy;
- begin
- FEnumerator.Free;
- inherited Destroy;
- end;
- { TObjectEnumerable }
- function TObjectEnumerable.GetEnumerator: IEnumerator<TObject>;
- begin
- Result := TObjectEnumerator.Create(FEnumerable.GetEnumerator, FEnumerable);
- end;
- constructor TObjectEnumerable.Create(const AItems: array of TObject);
- begin
- FEnumerable := TObjectList.Create;
- FEnumerable.AddRange(AItems);
- end;
- { TObjectEnumerator }
- function TObjectEnumerator.GetCurrent: TObject;
- begin
- Result := FEnumerator.Current;
- end;
- function TObjectEnumerator.MoveNext: Boolean;
- begin
- Result := FEnumerator.MoveNext;
- end;
- procedure TObjectEnumerator.Reset;
- begin
- FEnumerator.Free;
- FEnumerator := FCollection.GetEnumerator;
- end;
- constructor TObjectEnumerator.Create(AEnumerator: TObjectList.TEnumerator; ACollection: TObjectList);
- begin
- FEnumerator := AEnumerator;
- FCollection := ACollection;
- end;
- destructor TObjectEnumerator.Destroy;
- begin
- FEnumerator.Free;
- inherited Destroy;
- end;
- end.
|