123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- unit tccomponent;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, fpcunit, testutils, testregistry;
- type
- { TEventSink }
- TEventSink = Class(TObject)
- FEventCount : Integer;
- FLastSender : TObject;
- Procedure Event(Sender : TObject); virtual;
- Procedure ResetEvent;
- end;
- { TNotification }
-
- TNotification = Class(TCollectionItem)
- Public
- ASender,
- AComponent : TComponent;
- AOperation : TOperation;
- end;
- { TNotificationSink }
- TNotificationSink = Class(TObject)
- private
- Fevents : TCollection;
- function GetNot(Index : Integer): TNotification;
- Public
- Destructor Destroy; override;
- procedure Notification(Sender, AComponent: TComponent; Operation: TOperation); virtual;
- Procedure Reset;
- Function EventCount : Integer;
- Property Notifications [Index : Integer] : TNotification Read GetNot;
- end;
- { TMyComponent }
- TNotificationEvent = procedure (Sender : TComponent; AComponent: TComponent; Operation: TOperation) of object;
- TMyComponent = Class(TComponent)
- private
- FOnDestroy: TNotifyEvent;
- FOnNotify: TNotificationEvent;
- Public
- Destructor Destroy; override;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- Property OnDestroy : TNotifyEvent Read FOnDestroy Write FOnDestroy;
- Property OnNotification : TNotificationEvent Read FOnNotify Write FOnNotify;
- end;
- { TTestTComponentBase }
- TTestTComponentBase = class(TTestCase)
- protected
- FRoot : TMyComponent;
- Procedure CreateComponents(ACount : Integer);
- Procedure CreateComponents(ACount : Integer; Const BaseName : String);
- Procedure CreateComponents(ACount : Integer; AClass : TComponentClass);
- Procedure CreateComponents(ACount : Integer; AClass : TComponentClass; Const BaseName : String);
- procedure SetUp; override;
- procedure TearDown; override;
- end;
-
- { TTestTComponent }
- TTestTComponent = Class(TTestTComponentBase)
- private
- procedure TestDoubleName;
- procedure TestTextName;
- procedure TestNumberName;
- procedure TestNumberTextName;
- Published
- Procedure TestCreate;
- Procedure TestName;
- procedure TestIdentiFierName;
- procedure TestIdentiFierNameTwo;
- procedure TestIdentiFierNameThree;
- procedure TestIdentiFierNameFour;
- procedure TestOwner;
- procedure TestChildren;
- Procedure TestDestroyChild;
- Procedure TestDestroyChildren;
- Procedure TestUniqueName;
- Procedure TestRemoveComponent;
- end;
-
- { TTestTComponentNotifies }
- TTestTComponentNotifies = Class(TTestTComponentBase)
- Protected
- N : TNotificationSink;
- procedure SetUp; override;
- procedure TearDown; override;
- Published
- Procedure TestInsertNotification;
- Procedure TestRemoveNotification;
- end;
- implementation
- procedure TTestTComponentBase.CreateComponents(ACount: Integer);
- begin
- CreateComponents(ACount,'');
- end;
- procedure TTestTComponentBase.CreateComponents(ACount: Integer;
- const BaseName: String);
- begin
- CreateComponents(ACount,TMyComponent,BaseName);
- end;
- procedure TTestTComponentBase.CreateComponents(ACount: Integer;
- AClass: TComponentClass);
- begin
- CreateComponents(ACount,AClass,'');
- end;
- procedure TTestTComponentBase.CreateComponents(ACount: Integer;
- AClass: TComponentClass; const BaseName: String);
-
- Var
- I : Integer;
- C : TComponent;
-
- begin
- For I:=0 to ACount-1 do
- begin
- C:=TMyComponent.Create(FRoot);
- If (BaseName<>'') then
- C.Name:=BaseName+IntToStr(I+1);
- end;
- end;
- procedure TTestTComponentBase.SetUp;
- begin
- FRoot:=TMyComponent.Create(Nil);
- FRoot.Name:='Root';
- end;
- procedure TTestTComponentBase.TearDown;
- begin
- FreeAndNil(FRoot);
- end;
- { TTestTComponent }
- procedure TTestTComponent.TestCreate;
- begin
- FreeAndNil(Froot);
- FRoot:=TMyComponent.Create(Nil);
- AssertEquals('Empty name','',FRoot.Name);
- AssertEquals('No owned components',0,FRoot.ComponentCount);
- If (FRoot.ComponentState<>[]) then
- Fail('Componentstate is not empty');
- If (FRoot.Owner<>Nil) then
- Fail('Owner is not nil');
- end;
- procedure TTestTComponent.TestName;
- begin
- AssertEquals('Name is Root','Root',FRoot.Name);
- end;
- procedure TTestTComponent.TestOwner;
- Var
- C : TComponent;
- begin
- C:=TComponent.Create(FRoot);
- If (C.Owner<>FRoot) then
- Fail('Owner not saved after create');
- end;
- procedure TTestTComponent.TestChildren;
- begin
- CreateComponents(3,'Child');
- AssertEquals('Componentcount is 3',3,FRoot.ComponentCount);
- AssertEquals('Child component 0 is child1','Child1',FRoot.Components[0].Name);
- AssertEquals('Child component 1 is child2','Child2',FRoot.Components[1].Name);
- AssertEquals('Child component 2 is child3','Child3',FRoot.Components[2].Name);
- end;
- procedure TTestTComponent.TestDestroyChild;
- Var
- S : TEventSink;
- begin
- CreateComponents(1);
- S:=TEventSink.Create;
- try
- TMyComponent(FRoot.Components[0]).OnDestroy:[email protected];
- FreeAndNil(FRoot);
- AssertEquals('One child destroyed',1,S.FEventcount);
- If (S.FLastSender=Nil) then
- Fail('No sender passed');
- finally
- S.Free;
- end;
- end;
- procedure TTestTComponent.TestDestroyChildren;
- Var
- S : TEventSink;
- I : Integer;
- begin
- CreateComponents(3);
- S:=TEventSink.Create;
- try
- For I:=0 to 2 do
- TMyComponent(FRoot.Components[I]).OnDestroy:[email protected];
- FreeAndNil(FRoot);
- AssertEquals('One child destroyed',3,S.FEventcount);
- If (S.FLastSender=Nil) then
- Fail('No sender passed');
- finally
- S.Free;
- end;
- end;
- procedure TTestTComponent.TestDoubleName;
- begin
- FRoot.Components[1].Name:='Child1';
- end;
- procedure TTestTComponent.TestUniqueName;
- begin
- CreateComponents(3,'Child');
- AssertException('Unique name',EComponentError,@TestDoubleName);
- end;
- procedure TTestTComponent.TestRemoveComponent;
- Var
- C : TComponent;
- begin
- CreateComponents(1);
- C:=FRoot.Components[0];
- FRoot.RemoveComponent(C);
- Try
- AssertEquals('No components left',0,FRoot.ComponentCount);
- AssertSame('Component has no owner',Nil,C.Owner);
- Finally
- C.Free;
- end;
- end;
- procedure TTestTComponent.TestTextName;
- begin
- FRoot.Name:='Child 1';
- end;
- procedure TTestTComponent.TestNumberName;
- begin
- FRoot.Name:='1';
- end;
- procedure TTestTComponent.TestNumberTextName;
- begin
- FRoot.Name:='1Too';
- end;
- procedure TTestTComponent.TestIdentiFierName;
- begin
- AssertException('Identifier name',EComponentError,@TestTextName);
- end;
- procedure TTestTComponent.TestIdentiFierNameTwo;
- begin
- AssertException('Identifier name',EComponentError,@TestNumberTextName);
- end;
- procedure TTestTComponent.TestIdentiFierNameThree;
- begin
- AssertException('Identifier name',EComponentError,@TestNumberName);
- end;
- procedure TTestTComponent.TestIdentiFierNameFour;
- Var
- Failed : Boolean;
- begin
- Failed:=False;
- Try
- FRoot.Name:='Some1';
- except
- Failed:=True;
- end;
- If Failed then
- Fail('No identifier ending on 1 accepted ?');
- end;
- { TMyComponent }
- destructor TMyComponent.Destroy;
- begin
- If Assigned(FOnDestroy) then
- FOnDestroy(Self);
- inherited Destroy;
- end;
- procedure TMyComponent.Notification(AComponent: TComponent;
- Operation: TOperation);
- begin
- If Assigned(FOnNotify) then
- FOnNotify(Self, AComponent, Operation);
- inherited Notification(AComponent, Operation);
- end;
- { TEventSink }
- procedure TEventSink.Event(Sender: TObject);
- begin
- Inc(FEventCount);
- FLastSender:=Sender;
- end;
- procedure TEventSink.ResetEvent;
- begin
- FLastSender:=Nil;
- FEventCount:=0;
- end;
- { TNotificationSink }
- function TNotificationSink.GetNot(Index : Integer): TNotification;
- begin
- If Assigned(FEvents) then
- Result:=Nil
- else
- Result:=TNotification(FEvents.Items[Index]);
- end;
- destructor TNotificationSink.Destroy;
- begin
- FreeAndNil(FEvents);
- inherited Destroy;
- end;
- procedure TNotificationSink.Notification(Sender, AComponent: TComponent;
- Operation: TOperation);
-
- Var
- N : TNotification;
-
- begin
- If (Fevents=Nil) then
- FEvents:=TCollection.Create(TNotification);
- N:=FEvents.Add as TNotification;
- N.AComponent:=AComponent;
- N.ASender:=Sender;
- N.AOperation:=Operation;
- end;
- procedure TNotificationSink.Reset;
- begin
- FreeAndNil(FEvents);
- end;
- function TNotificationSink.EventCount: Integer;
- begin
- If (Fevents<>Nil) then
- Result:=FEvents.Count
- else
- Result:=0;
- end;
- { TTestTComponentNotifies }
- procedure TTestTComponentNotifies.SetUp;
- begin
- inherited SetUp;
- N:=TNotificationSink.Create;
- FRoot.OnNotification:[email protected];
- end;
- procedure TTestTComponentNotifies.TearDown;
- begin
- FreeAndNil(N);
- inherited TearDown;
- end;
- procedure TTestTComponentNotifies.TestInsertNotification;
- Var
- C : TComponent;
- E : TNotification;
- begin
- CreateComponents(1);
- AssertEquals('One notification received',1,N.EventCount);
- E:=N.Notifications[0];
- AssertEquals('Insert notification received',Ord(opInsert),Ord(E.AOperation));
- end;
- procedure TTestTComponentNotifies.TestRemoveNotification;
- Var
- C : TComponent;
- E : TNotification;
- begin
- CreateComponents(1);
- N.Reset;
- C:=FRoot.Components[0];
- FRoot.RemoveComponent(C);
- Try
- AssertEquals('One notification received',1,N.EventCount);
- E:=N.Notifications[0];
- Finally
- C.Free;
- end;
- end;
- initialization
- RegisterTests([TTestTComponent,TTestTComponentNotifies]);
- end.
|