{ $Id$} { Copyright (C) 2006 Vincent Snijders This source is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This code 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. See the GNU General Public License for more details. A copy of the GNU General Public License is available on the World Wide Web at . You can also obtain it by writing to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. } unit TestLpi; {$mode objfpc}{$H+} interface uses Classes, SysUtils, StrUtils, fpcunit, testregistry, process, UTF8Process, InterfaceBase, LCLPlatformDef, LazFileUtils, LazUTF8, FileUtil, TestGlobals; type { TLpkTest } TLpkTest = class(TTestCase) private FPath: string; public constructor Create(const APath: string; const ATestName: string); overload; class function GetExtension: string; virtual; class function CreateSuiteFromFile(const aName, APath: string): TTestSuite; virtual; class function CreateSuiteFromDirectory(const AName, ABasePath: string): TTestSuite; published procedure TestCompile; end; { TLpiTest } TLpiTest= class(TLpkTest) private procedure RunScript; public class function GetExtension: string; override; class function CreateSuiteFromFile(const aName, APath: string): TTestSuite; override; published procedure TestRun; end; implementation var LazarusDir: string; ComponentsDir: String; ExamplesDir: string; CTExamplesDir: string; LCLTestDir: string; ScriptEngine: string; procedure InitDirectories; begin LazarusDir := ExpandFileNameUTF8(ExtractFilePath(ParamStrUTF8(0)) + '../'); ComponentsDir := SetDirSeparators(LazarusDir + 'components/'); ExamplesDir := LazarusDir + 'examples' + PathDelim; CTExamplesDir := SetDirSeparators(ComponentsDir + 'codetools/examples/'); LCLTestDir := LazarusDir + 'lcl' + PathDelim + 'tests' + PathDelim; ScriptEngine := 'C:\Program Files\AutoHotkey\AutoHotKey.exe'; end; function GetScriptFileName(const LpiFileName: string): string; begin Result := AppendPathDelim(ProgramDirectory) + ExtractFileNameOnly(LpiFileName) +'.ahk'; end; constructor TLpkTest.Create(const APath: string; const ATestName: string); begin inherited CreateWithName(ATestName); FPath := APath; end; class function TLpkTest.GetExtension: string; begin Result := '.lpk'; end; class function TLpkTest.CreateSuiteFromDirectory(const AName, ABasePath: string): TTestSuite; procedure SearchDirectory(const ADirectory: string); var RelativePath: string; SearchMask: string; FileInfo: TSearchRec; begin SearchMask := ABasePath+ADirectory + '*'; if FindFirstUTF8(SearchMask,faAnyFile,FileInfo)=0 then begin repeat // skip special directory entries if (FileInfo.Name='.') or (FileInfo.Name='..') then continue; RelativePath := ADirectory+ FileInfo.Name; if RightStr(FileInfo.Name,4)=GetExtension then Result.AddTest(CreateSuiteFromFile(RelativePath, ABasePath+RelativePath)) else if (FileInfo.Attr and faDirectory=faDirectory) then SearchDirectory(AppendPathDelim(RelativePath)); until FindNextUTF8(FileInfo)<>0; end; FindCloseUTF8(FileInfo); end; begin Result := TTestSuite.Create(AName); SearchDirectory('') end; class function TLpkTest.CreateSuiteFromFile(const AName, APath: string): TTestSuite; begin Result := TTestSuite.Create(AnsiReplaceStr(AName, DirectorySeparator, '/')); Result.AddTest(Create(APath, 'TestCompile')); end; procedure TLpkTest.TestCompile; var LazBuildPath: string; LazBuild: TProcessUTF8; OutputLines: TStrings; CmdLine: string; begin LazBuildPath := LazarusDir + 'lazbuild' + GetExeExt; AssertTrue(LazBuildPath + ' does not exist', FileExistsUTF8(LazBuildPath)); LazBuild := TProcessUTF8.Create(nil); OutputLines := nil; try {$IFDEF windows} LazBuild.Options := [poNewConsole, poUsePipes]; {$ELSE} LazBuild.Options := [poNoConsole, poUsePipes]; {$ENDIF} LazBuild.ShowWindow := swoHIDE; CmdLine:=LazBuildPath; if Compiler<>'' then CmdLine:=Cmdline + ' --compiler='+Compiler; if PrimaryConfigPath<>'' then CmdLine := CmdLine + ' --pcp='+PrimaryConfigPath; Cmdline := Cmdline + ' --ws=' + LCLPlatformDirNames[WidgetSet.LCLPlatform]; Cmdline := Cmdline + ' -B ' + FPath; LazBuild.CommandLine := CmdLine; LazBuild.CurrentDirectory := ExtractFileDir(FPath); LazBuild.Execute; OutputLines := ReadOutput(LazBuild); if LazBuild.Running then begin LazBuild.Terminate(99); end; if LazBuild.ExitStatus<>0 then Fail(format('Compilation failed: ExitCode=%d%s%s', [LazBuild.ExitStatus, LineEnding, AnsiToUtf8(OutputLines.Text)])); finally LazBuild.Free; OutputLines.Free; end; end; class function TLpiTest.GetExtension: string; begin Result := '.lpi'; end; class function TLpiTest.CreateSuiteFromFile(const AName, APath: string): TTestSuite; {$IFDEF win32} var AhkFileName: String; {$ENDIF} begin Result := inherited CreateSuiteFromFile(AName, APath); {$IFDEF win32} AhkFileName := GetScriptFileName(APath); if FileExistsUTF8(AhkFileName) then Result.AddTest(TLpiTest.Create(APath, 'TestRun')); {$ELSE} {$NOTE scripting is only available on win32} {$ENDIF} end; procedure TLpiTest.RunScript; var ScriptProcess : TProcessUTF8; begin AssertTrue('ScriptEngine "' + ScriptEngine + '" does not exist.', FileExistsUTF8(ScriptEngine)); ScriptProcess := TProcessUTF8.Create(nil); try ScriptProcess.CommandLine := ScriptEngine + ' ' + GetScriptFileName(FPath); ScriptProcess.Execute; ScriptProcess.WaitOnExit; finally ScriptProcess.Free; end; end; procedure TLpiTest.TestRun; var TestProcess : TProcessUTF8; ExeName: string; begin ExeName := ChangeFileExt(FPath, GetExeExt); AssertTrue(ExeName + 'does not exist.', FileExistsUTF8(ExeName)); TestProcess := TProcessUTF8.Create(nil); try TestProcess.CommandLine := ExeName; TestProcess.Execute; RunScript; TestProcess.WaitOnExit; finally TestProcess.Free; end; end; procedure InitializeTestSuites; var ATestSuite: TTestSuite; begin // Create testsuite for projects ATestSuite := TTestSuite.Create('Projects'); ATestSuite.AddTest( TLpiTest.CreateSuiteFromDirectory('Examples', ExamplesDir)); ATestSuite.AddTest( TLpiTest.CreateSuiteFromDirectory('Codetools Examples', CTExamplesDir)); ATestSuite.AddTest( TLpiTest.CreateSuiteFromDirectory('LCL test', LCLTestDir)); GetTestRegistry.AddTest(ATestSuite); // Create testsuite for packages ATestSuite := TTestSuite.Create('Packages'); ATestSuite.AddTest( TLpkTest.CreateSuiteFromDirectory('Components', ComponentsDir)); ATestSuite.AddTest( TLpkTest.CreateSuiteFromDirectory('Examples', ExamplesDir)); GetTestRegistry.AddTest(ATestSuite); end; initialization InitDirectories; InitializeTestSuites; end.