123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- unit utdirwatch;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, fpcunit, testutils, testregistry, dirwatch;
- type
- TChangedEntry = record
- Dir : TWatchDirectoryEntry;
- Events : TWatchFileEvents;
- FN : String;
- end;
- TChangedEntryArray = Array of TChangedEntry;
- { TTestDirWatch }
- TTestDirWatch= class(TTestCase)
- private
- FDirWatch: TDirwatch;
- FTestDir: string;
- FChanged: TChangedEntryArray;
- FCheckCount : Integer;
- FMaxLoopCount : Integer;
- FDoCheckOne : TNotifyEvent;
- procedure AssertChange(const Msg: String; aIndex: Integer; aEntry: TWatchDirectoryEntry; aEvents: TWatchFileEvents; const aFileName : string = '');
- procedure CleanDirs(aDir: String);
- procedure DoAppendFile(const aName: string);
- procedure DoChange(Sender: TObject; const aEvent: TFileChangeEvent);
- procedure DoCheck(sender: TObject; var aContinue: Boolean);
- procedure DoCreateFile(const aName: string);
- procedure DoDeleteFile(const aName: string);
- procedure HandleCreateFile(Sender: TObject);
- protected
- procedure SetUp; override;
- procedure TearDown; override;
- property dirwatch : TDirwatch read FDirWatch;
- Property TestDir : string Read FTestDir;
- property CheckCount : Integer Read FCheckCount;
- property MaxLoopCount : Integer Read FMaxLoopCount Write FMaxLoopCount;
- Public
- class procedure AssertEquals(const Msg: String; aExpected, aActual: TWatchFileEvents); overload;
- published
- procedure TestHookUp;
- procedure TestAddFile;
- procedure TestAppendFile;
- procedure TestDeleteFile;
- procedure TestLoopNoThread;
- procedure TestLoopThread;
- procedure TestAddFileBaseDir;
- end;
- implementation
- uses typinfo, inifiles;
- var
- BaseDir : String;
- procedure TTestDirWatch.CleanDirs(aDir: String);
- Var
- Info : TSearchRec;
- lDir,lFull : String;
- begin
- lDir:=IncludeTrailingPathDelimiter(aDir);
- If FIndFirst(lDir+AllFilesMask,sysutils.faDirectory,Info)=0 then
- try
- Repeat
- lFull:=lDir+Info.Name;
- if (Info.Attr and faDirectory)<>0 then
- begin
- if not ((Info.Name='.') or (Info.Name='..')) then
- begin
- CleanDirs(lFull);
- if not RemoveDir(lFull) then
- Fail('Failed to remove directory %s',[lFull])
- end;
- end
- else if not DeleteFIle(lFull) then
- Fail('Failed to remove file %s',[lFull])
- until FIndNext(Info)<>0;
- finally
- FindClose(Info);
- end;
- end;
- procedure TTestDirWatch.DoChange(Sender: TObject; const aEvent: TFileChangeEvent);
- var
- Len : Integer;
- begin
- len:=Length(FChanged);
- SetLength(FChanged,Len+1);
- FChanged[Len].Dir:=aEvent.Entry;
- FChanged[Len].Events:=aEvent.Events;
- FChanged[Len].FN:=aEvent.FileName;
- end;
- procedure TTestDirWatch.DoCheck(sender: TObject; var aContinue: Boolean);
- begin
- aContinue:=CheckCount<MaxLoopCount;
- if (FCheckCount=0) then
- if Assigned(FDoCheckOne) then
- FDoCheckOne(Self);
- inc(FCheckCount);
- end;
- procedure TTestDirWatch.TestHookUp;
- begin
- AssertNotNull('Have watch',Dirwatch);
- AssertEquals('No watches',0,Dirwatch.Watches.Count);
- AssertTrue('Have test dir',TestDir<>'');
- AssertTrue('test dir exists',DirectoryExists(TestDir));
- AssertEquals('No max check count',0,FMaxLoopCount);
- AssertEquals('No check count',0,FCheckCount);
- AssertTrue('No docheckone',FDoCheckOne=nil);
- end;
- procedure TTestDirWatch.DoAppendFile(const aName : string);
- var
- FD : THandle;
- begin
- FD:=FileOpen(TestDir+aName,fmOpenWrite);
- try
- FileSeek(FD,0,fsFromEnd);
- if FileWrite(FD,aName[1],Length(aName))=-1 then
- Writeln(GetLastOSError);
- finally
- FileClose(FD);
- end;
- end;
- procedure TTestDirWatch.DoCreateFile(const aName : string);
- var
- L: TStrings;
- begin
- L:=TStringList.Create;
- try
- L.Add(aName);
- L.SaveToFile(TestDir+aName);
- finally
- L.Free;
- end;
- end;
- procedure TTestDirWatch.DoDeleteFile(const aName: string);
- begin
- If not DeleteFile(TestDir+aName) then
- Fail('Failed to delete file '+TestDir+aName);
- end;
- procedure TTestDirWatch.HandleCreateFile(Sender: TObject);
- begin
- DoCreateFile('name.txt');
- end;
- class procedure TTestDirWatch.AssertEquals(const Msg: String; aExpected,aActual : TWatchFileEvents);
- begin
- AssertEquals(Msg,SetToString(PTypeInfo(TypeInfo(TWatchFileEvents)),Longint(aExpected),False),
- SetToString(PTypeInfo(TypeInfo(TWatchFileEvents)),Longint(aActual),False));
- end;
- procedure TTestDirWatch.AssertChange(const Msg: String; aIndex: Integer; aEntry: TWatchDirectoryEntry; aEvents: TWatchFileEvents;
- const aFileName: string);
- var
- M : String;
- begin
- M:=Msg+Format(' [%d]: ',[aIndex]);
- AssertTrue(M+'correct index',aIndex<Length(FChanged));
- AssertSame(M+'correct dir entry',aEntry,FChanged[aIndex].Dir);
- AssertEquals(M+'correct changes',aEvents,FChanged[aIndex].Events);
- if aFileName<>'' then
- AssertEquals(M+'correct fileName',aFileName,FChanged[aIndex].FN);
- end;
- procedure TTestDirWatch.TestAddFile;
- begin
- FDirwatch.AddWatch(TestDir,[feCreate]);
- FDirWatch.InitWatch;
- DoCreateFile('name.txt');
- AssertEquals(1,FDirWatch.Check);
- AssertChange('Create',0,FDirWatch.Watches[0],[feCreate],'name.txt');
- end;
- procedure TTestDirWatch.TestAppendFile;
- begin
- FDirwatch.AddWatch(TestDir,[feModify]);
- DoCreateFile('name.txt');
- FDirWatch.InitWatch;
- DoAppendFile('name.txt');
- AssertEquals('Change detected',1,FDirWatch.Check);
- AssertChange('Change detected',0,FDirWatch.Watches[0],[feModify],'name.txt');
- end;
- procedure TTestDirWatch.TestDeleteFile;
- begin
- FDirwatch.AddWatch(TestDir,[feDelete]);
- DoCreateFile('name.txt');
- FDirWatch.InitWatch;
- DoDeleteFile('name.txt');
- AssertEquals('Change detected',1,FDirWatch.Check);
- AssertChange('Change detected',0,FDirWatch.Watches[0],[feDelete],'name.txt');
- end;
- procedure TTestDirWatch.TestLoopNoThread;
- begin
- FDirwatch.AddWatch(TestDir,[feCreate]);
- FDirwatch.OnCheck:=@DoCheck;
- FDoCheckOne:=@HandleCreateFile;
- MaxLoopCount:=2;
- FDirWatch.StartLoop;
- AssertChange('Change detected',0,FDirWatch.Watches[0],[feCreate],'name.txt');
- end;
- procedure TTestDirWatch.TestLoopThread;
- var
- I : Integer;
- begin
- FDirwatch.AddWatch(TestDir,[feCreate]);
- FDirwatch.Threaded:=True;
- FDirWatch.StartLoop;
- Sleep(50);
- DoCreateFile('name.txt');
- I:=0;
- Repeat
- Sleep(10);
- CheckSynchronize;
- inc(i);
- until (I>=50) or (length(FChanged)>0);
- AssertChange('Change detected',0,FDirWatch.Watches[0],[feCreate],'name.txt');
- end;
- procedure TTestDirWatch.TestAddFileBaseDir;
- begin
- FDirwatch.BaseDir:=TestDir;
- AssertTrue('Create Subdir ',ForceDirectories(TestDir+'sub'));
- FDirwatch.AddWatch('',[feCreate]);
- FDirWatch.InitWatch;
- DoCreateFile('sub/name.txt');
- AssertEquals('Subdirs not watched',0,FDirWatch.Check);
- end;
- procedure TTestDirWatch.SetUp;
- begin
- FDirWatch:=TDirwatch.Create(Nil);
- FTestDir:=IncludeTrailingPathDelimiter(BaseDir);
- ForceDirectories(TestDir);
- FDirWatch.OnChange:=@DoChange;
- FMaxLoopCount:=0;
- FCheckCount:=0;
- FDoCheckOne:=Nil;
- end;
- procedure TTestDirWatch.TearDown;
- begin
- CleanDirs(TestDir);
- FDirWatch.Free;
- end;
- procedure GetBaseDir;
- var
- FN : string;
- begin
- BaseDir:=IncludeTrailingPathDelimiter(GetTempDir)+'Dirwatch'+PathDelim;
- FN:=ExtractFilePath(ParamStr(0))+'config.ini';
- If FileExists(FN) then
- With TMemIniFile.Create(FN) do
- try
- BaseDir:=ReadString('dirwatch','basedir',BaseDir);
- finally
- Free;
- end;
- end;
- initialization
- GetBaseDir;
- RegisterTest(TTestDirWatch);
- end.
|