added fpcunit test runner and fpcunit test runner ide package

git-svn-id: trunk@6314 -
This commit is contained in:
vincents 2004-11-29 11:59:02 +00:00
parent 7eedd59d2a
commit 7dd0235a0d
13 changed files with 4023 additions and 4 deletions

11
.gitattributes vendored
View File

@ -61,6 +61,17 @@ components/codetools/resourcecodetool.pas svneol=native#text/pascal
components/codetools/sourcechanger.pas svneol=native#text/pascal
components/codetools/sourcelog.pas svneol=native#text/pascal
components/codetools/stdcodetools.pas svneol=native#text/pascal
components/fpcunit/fpcunittestrunner.lpk svneol=native#text/pascal
components/fpcunit/fpcunittestrunner.pas svneol=native#text/pascal
components/fpcunit/guitestrunner.lfm svneol=native#text/plain
components/fpcunit/guitestrunner.lrs svneol=native#text/pascal
components/fpcunit/guitestrunner.pas svneol=native#text/pascal
components/fpcunit/ide/README.txt svneol=native#text/plain
components/fpcunit/ide/fpcunitide.lpk svneol=native#text/pascal
components/fpcunit/ide/fpcunitide.pas svneol=native#text/pascal
components/fpcunit/ide/fpcunitlazideintf.pas svneol=native#text/pascal
components/fpcunit/ide/lib/README.txt svneol=native#text/plain
components/fpcunit/lib/README.txt svneol=native#text/plain
components/gtk/gtkglarea/gtkglarea.lrs svneol=native#text/pascal
components/gtk/gtkglarea/gtkglarea_int.pp svneol=native#text/pascal
components/gtk/gtkglarea/gtkglareacontrol.pas svneol=native#text/pascal

View File

@ -0,0 +1,47 @@
<?xml version="1.0"?>
<CONFIG>
<Package Version="2">
<PathDelim Value="\"/>
<Name Value="FPCUnitTestRunner"/>
<Author Value="Vincent Snijders"/>
<CompilerOptions>
<Version Value="2"/>
<PathDelim Value="\"/>
<SearchPaths>
<UnitOutputDirectory Value="lib\"/>
</SearchPaths>
<CodeGeneration>
<Generate Value="Faster"/>
</CodeGeneration>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Description Value="FPCUnit gui test runner form"/>
<License Value="LGPL"/>
<Version Minor="1"/>
<Files Count="1">
<Item1>
<Filename Value="guitestrunner.pas"/>
<UnitName Value="GuiTestRunner"/>
</Item1>
</Files>
<RequiredPkgs Count="2">
<Item1>
<PackageName Value="LCL"/>
<MinVersion Major="1" Valid="True"/>
</Item1>
<Item2>
<PackageName Value="FCL"/>
<MinVersion Major="1" Valid="True"/>
</Item2>
</RequiredPkgs>
<UsageOptions>
<UnitPath Value="$(PkgOutDir)\"/>
</UsageOptions>
<PublishOptions>
<Version Value="2"/>
<IgnoreBinaries Value="False"/>
</PublishOptions>
</Package>
</CONFIG>

View File

@ -0,0 +1,15 @@
{ This file was automatically created by Lazarus. Do not edit!
This source is only used to compile and install
the package FPCUnitTestRunner 0.1.
}
unit FPCUnitTestRunner;
interface
uses
GuiTestRunner;
implementation
end.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,323 @@
unit GuiTestRunner;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls,
Buttons, ComCtrls, ActnList, Menus, Clipbrd, StdCtrls,
testreport, fpcunit, testregistry;
const
S_OK = 0; {$EXTERNALSYM S_OK}
S_FALSE = $00000001; {$EXTERNALSYM S_FALSE}
E_NOINTERFACE = HRESULT($80004002); {$EXTERNALSYM E_NOINTERFACE}
type
TGUITestRunner = class(TForm, ITestListener)
actCopy: TAction;
actCut: TAction;
ActionList1: TActionList;
BitBtn1: TBitBtn;
btnRun: TBitBtn;
ComboBox1: TComboBox;
ImageList1: TImageList;
ImageList2: TImageList;
Label1: TLabel;
Memo1: TMemo;
MenuItem1: TMenuItem;
MenuItem2: TMenuItem;
MenuItem3: TMenuItem;
PopupMenu1: TPopupMenu;
PopupMenu2: TPopupMenu;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
XMLMemo: TMemo;
PaintBox1: TPaintBox;
Panel4: TPanel;
Panel5: TPanel;
Splitter1: TSplitter;
PageControl1: TPageControl;
Panel1: TPanel;
Panel2: TPanel;
Panel3: TPanel;
tsTestTree: TTabSheet;
tsResultsXML: TTabSheet;
TreeView1: TTreeView;
procedure BitBtn1Click(Sender: TObject);
procedure GUITestRunnerCreate(Sender: TObject);
procedure GUITestRunnerDestroy(Sender: TObject);
procedure MenuItem3Click(Sender: TObject);
procedure PaintBox1Click(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
procedure TreeView1Click(Sender: TObject);
procedure XMLMemoChange(Sender: TObject);
procedure actCopyExecute(Sender: TObject);
procedure actCutExecute(Sender: TObject);
procedure btnRunClick(Sender: TObject);
private
{ private declarations }
suiteList: TStringList;
currentTestNode: TTreeNode;
EnabledTestsCount: Integer;
failureCounter: Integer;
errorCounter: Integer;
testsCounter: Integer;
barColor: TColor;
protected
{ IInterface }
function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
public
procedure AddFailure(ATest: TTest; AFailure: TTestFailure);
procedure AddError(ATest: TTest; AError: TTestFailure);
procedure StartTest(ATest: TTest);
procedure EndTest(ATest: TTest);
procedure DrawBar;
end;
var
TestRunner: TGUITestRunner;
implementation
{ TGUITestRunner }
procedure TGUITestRunner.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
end;
procedure TGUITestRunner.TreeView1Click(Sender: TObject);
var
Node: TTreeNode;
begin
if TreeView1.Selected <> nil then
begin
Memo1.Lines.Clear;
Node := TreeView1.Selected;
if (Node.Level = 2) then
if (TObject(Node.Data) is TTestFailure) then
begin
Memo1.Lines.Add('Exception Message: ' + TTestFailure(Node.Data).ExceptionMessage);
Memo1.Lines.Add('Exception Class Name: ' + TTestFailure(Node.Data).ExceptionClassName);
if TTestFailure(Node.Data).SourceUnitName <> '' then
begin
Memo1.Lines.Add('Unit Name: ' + TTestFailure(Node.Data).SourceUnitName);
Memo1.Lines.Add('Method Name: ' + TTestFailure(Node.Data).MethodName);
Memo1.Lines.Add('Line Number: ' + IntToStr(TTestFailure(Node.Data).LineNumber));
end;
end;
end;
end;
procedure TGUITestRunner.XMLMemoChange(Sender: TObject);
begin
end;
procedure TGUITestRunner.actCopyExecute(Sender: TObject);
begin
Clipboard.AsText := XMLMemo.Lines.Text;
end;
procedure TGUITestRunner.actCutExecute(Sender: TObject);
begin
Clipboard.AsText := XMLMemo.Lines.Text;
XMLMemo.Lines.Clear;
end;
procedure TGUITestRunner.GUITestRunnerCreate(Sender: TObject);
var
i: integer;
begin
suiteList := TStringList.Create;
barColor := clGray;
for i := 0 to GetTestRegistry.Tests.Count - 1 do
ComboBox1.Items.Add(GetTestRegistry.Test[i].TestName);
ComboBox1.ItemIndex := 0;
end;
procedure TGUITestRunner.BitBtn1Click(Sender: TObject);
begin
Close;
end;
procedure TGUITestRunner.GUITestRunnerDestroy(Sender: TObject);
begin
suiteList.Free;
end;
procedure TGUITestRunner.MenuItem3Click(Sender: TObject);
begin
Clipboard.AsText := Memo1.Lines.Text;
end;
procedure TGUITestRunner.PaintBox1Click(Sender: TObject);
begin
end;
procedure TGUITestRunner.PaintBox1Paint(Sender: TObject);
var
msg: string;
begin
with PaintBox1 do
begin
Canvas.Brush.Color := clGray;
Canvas.Rectangle(0, 0, Width, Height);
if (FailureCounter = 0) and (ErrorCounter = 0) then
barColor := clGreen;
Canvas.Brush.Color := barColor;
if TestsCounter <> 0 then
begin
Canvas.Rectangle(0, 0, round((TestsCounter{- FailureCounter- ErrorCounter})/EnabledTestsCount*
Width), Height);
Canvas.Font.Color := clWhite;
msg := 'Runs: ' + IntToStr(TestsCounter);
if ErrorCounter <> 0 then
msg := msg + ' Number of test errors: ' + IntToStr(ErrorCounter);
if (FailureCounter <> 0) then
msg := msg + ' Number of test failures: ' + IntToStr(FailureCounter);
Canvas.Textout(10, 10, msg)
end;
end;
end;
procedure TGUITestRunner.btnRunClick(Sender: TObject);
var
testResult: TTestResult;
testSuite: TTest;
begin
TreeView1.items.Clear;
suiteList.Clear;
currentTestNode := nil;
if ComboBox1.ItemIndex = 0 then
testSuite := GetTestRegistry
else
testSuite := GetTestRegistry[ComboBox1.itemindex - 1];
enabledTestsCount := testSuite.CountTestCases;
failureCounter := 0;
errorCounter := 0;
testsCounter := 0;
testResult := TTestResult.Create;
try
testResult.AddListener(self);
testSuite.Run(testResult);
XMLMemo.lines.text:= TestResultAsXML(testResult);
finally
testResult.Free;
end;
PaintBox1.invalidate;
end;
procedure TGUITestRunner.AddFailure(ATest: TTest; AFailure: TTestFailure);
var
node: TTreeNode;
begin
node := TreeView1.Items.AddChildObject(currentTestNode, 'Message: ' + AFailure.ExceptionMessage, AFailure);
node.ImageIndex := 4;
node.SelectedIndex := 4;
node := TreeView1.Items.AddChildObject(currentTestNode, 'Exception: ' + AFailure.ExceptionClassName, AFailure);
node.ImageIndex := 4;
node.SelectedIndex := 4;
currentTestNode.ImageIndex := 3;
currentTestNode.SelectedIndex := 3;
node := TTreeNode(suiteList.Objects[suiteList.IndexOf(ATest.TestSuiteName)]);
node.ImageIndex := 3;
node.SelectedIndex := 3;
Inc(failureCounter);
if BarColor <> clRed then
barColor := clFuchsia;
end;
procedure TGUITestRunner.AddError(ATest: TTest; AError: TTestFailure);
var
node: TTreeNode;
begin
node := TreeView1.Items.AddChildObject(currentTestNode, 'Exception message: ' + AError.ExceptionMessage, AError);
node.ImageIndex := 4;
node.SelectedIndex := 4;
node := TreeView1.Items.AddChildObject(currentTestNode, 'Exception class: ' + AError.ExceptionClassName, AError);
node.ImageIndex := 4;
node.SelectedIndex := 4;
node := TreeView1.Items.AddChildObject(currentTestNode, 'Unit name: ' + AError.SourceUnitName, AError);
node.ImageIndex := 11;
node.SelectedIndex := 11;
node := TreeView1.Items.AddChildObject(currentTestNode, 'Method name: ' + AError.MethodName, AError);
node.ImageIndex := 11;
node.SelectedIndex := 11;
node := TreeView1.Items.AddChildObject(currentTestNode, 'Line number: ' + IntToStr(AError.LineNumber), AError);
node.ImageIndex := 11;
node.SelectedIndex := 11;
currentTestNode.ImageIndex := 2;
currentTestNode.SelectedIndex := 2;
node := TTreeNode(suiteList.Objects[suiteList.IndexOf(ATest.TestSuiteName)]);
node.ImageIndex := 2;
node.SelectedIndex := 2;
Inc(errorCounter);
barColor := clRed;
end;
procedure TGUITestRunner.StartTest(ATest: TTest);
var
parentNode: TTreeNode;
begin
if suiteList.IndexOf(ATest.TestSuiteName) <> -1 then
begin
parentNode := TTreeNode(suiteList.Objects[suiteList.IndexOf(ATest.TestSuiteName)]);
end
else
begin
if TreeView1.Items.Count = 0 then
begin
parentNode := TreeView1.Items.AddFirst(nil, ATest.TestSuiteName);
end
else
parentNode := TreeView1.Items.Add(TTreeNode(suiteList.Objects[SuiteList.Count - 1]), ATest.TestSuiteName);
suiteList.AddObject(ATest.TestSuiteName, parentNode);
end;
currentTestNode := TreeView1.Items.AddChildObject(parentNode, ATest.TestName, ATest);
Application.ProcessMessages;
end;
procedure TGUITestRunner.EndTest(ATest: TTest);
begin
Inc(testsCounter);
PaintBox1.invalidate;
Application.ProcessMessages;
end;
procedure TGUITestRunner.DrawBar;
begin
end;
{ TGUITestRunner.IInterface }
function TGUITestRunner.QueryInterface(const IID: TGUID; out Obj): HResult; StdCall;
begin
if GetInterface(IID, Obj) then Result := S_OK
else Result := E_NOINTERFACE
end;
function TGUITestRunner._AddRef: Integer; StdCall;
begin
Result := -1;
end;
function TGUITestRunner._Release: Integer; StdCall;
begin
Result := -1;
end;
initialization
{$I guitestrunner.lrs}
end.

View File

@ -0,0 +1,16 @@
Package CGILazIDE
This package is a designtime package for the Lazarus IDE.
It adds a new project type and a new unit type to the IDE.
New Project Type:
CGI Application - A Free Pascal program for CGI
using TCgiApplication for the main source (normally hidden,
just like the .lpr file for a normal Application).
New Unit Type:
CGI Module - A unit with a TCGIDatamodule.

View File

@ -0,0 +1,46 @@
<?xml version="1.0"?>
<CONFIG>
<Package Version="2">
<PathDelim Value="\"/>
<Name Value="fpcunitide"/>
<Author Value="Vincent Snijders"/>
<CompilerOptions>
<Version Value="2"/>
<PathDelim Value="\"/>
<SearchPaths>
<UnitOutputDirectory Value="lib\"/>
<SrcPath Value="$(LazarusDir)\ideintf\"/>
</SearchPaths>
<CodeGeneration>
<Generate Value="Faster"/>
</CodeGeneration>
<Other>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>
<Version Minor="1"/>
<Files Count="1">
<Item1>
<Filename Value="fpcunitlazideintf.pas"/>
<HasRegisterProc Value="True"/>
<UnitName Value="FPCUnitLazIDEIntf"/>
</Item1>
</Files>
<Type Value="DesignTime"/>
<RequiredPkgs Count="2">
<Item1>
<PackageName Value="IDEIntf"/>
</Item1>
<Item2>
<PackageName Value="FCL"/>
</Item2>
</RequiredPkgs>
<UsageOptions>
<UnitPath Value="$(PkgOutDir)\"/>
</UsageOptions>
<PublishOptions>
<Version Value="2"/>
<IgnoreBinaries Value="False"/>
</PublishOptions>
</Package>
</CONFIG>

View File

@ -0,0 +1,22 @@
{ This file was automatically created by Lazarus. Do not edit!
This source is only used to compile and install
the package fpcunitide 0.1.
}
unit fpcunitide;
interface
uses
FPCUnitLazIDEIntf, LazarusPackageIntf;
implementation
procedure Register;
begin
RegisterUnit('FPCUnitLazIDEIntf', @FPCUnitLazIDEIntf.Register);
end;
initialization
RegisterPackage('fpcunitide', @Register);
end.

View File

@ -0,0 +1,208 @@
{ Copyright (C) 2004 Vincent Snijders
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
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. See the GNU Library General Public License
for more details.
You should have received a copy of the GNU Library General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Abstract:
This unit adds a new project type and a new unit type to the IDE.
New Project Type:
FPCUnit Application - A Free Pascal program for FPCUnit tests.
New Unit Type:
FPCUnit test - A unit with a unit test.
See the README file for more information.
}
unit FPCUnitLazIDEIntf;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LazIDEIntf, ProjectIntf;
type
{ TFPCUnitApplicationDescriptor }
TFPCUnitApplicationDescriptor = class(TProjectDescriptor)
public
constructor Create; override;
function GetLocalizedName: string; override;
function GetLocalizedDescription: string; override;
procedure InitProject(AProject: TLazProject); override;
procedure CreateStartFiles(AProject: TLazProject); override;
end;
{ TFileDescPascalUnitFPCUnitTestCase }
TFileDescPascalUnitFPCUnitTestCase = class(TFileDescPascalUnit)
public
constructor Create; override;
function GetInterfaceUsesSection: string; override;
function GetLocalizedName: string; override;
function GetLocalizedDescription: string; override;
function GetInterfaceSource(const Filename, SourceName,
ResourceName: string): string;override;
function GetImplementationSource(const Filename, SourceName,
ResourceName: string): string; override;
end;
var
ProjectDescriptorFPCUnitApplication: TFPCUnitApplicationDescriptor;
FileDescriptorFPCUnitTestCase: TFileDescPascalUnitFPCUnitTestCase;
procedure Register;
implementation
procedure Register;
begin
FileDescriptorFPCUnitTestCase:=TFileDescPascalUnitFPCUnitTestCase.Create;
RegisterProjectFileDescriptor(FileDescriptorFPCUnitTestCase);
ProjectDescriptorFPCUnitApplication:=TFPCUnitApplicationDescriptor.Create;
RegisterProjectDescriptor(ProjectDescriptorFPCUnitApplication);
end;
{ TFPCUnitApplicationDescriptor }
constructor TFPCUnitApplicationDescriptor.Create;
begin
inherited Create;
Name:='FPCUnitApplication';
end;
function TFPCUnitApplicationDescriptor.GetLocalizedName: string;
begin
Result:='FPCUnit Test Application';
end;
function TFPCUnitApplicationDescriptor.GetLocalizedDescription: string;
var
le: string;
begin
le := System.LineEnding;
Result:='FPCUnit Test Application'+le+le
+'An application to run fpcunit test cases.'+le
+'The program file is '
+'automatically maintained by Lazarus.';
end;
procedure TFPCUnitApplicationDescriptor.InitProject(AProject: TLazProject);
var
le: string;
NewSource: String;
MainFile: TLazProjectFile;
begin
inherited InitProject(AProject);
MainFile:=AProject.CreateProjectFile('fpcunitproject1.lpr');
MainFile.IsPartOfProject:=true;
AProject.AddFile(MainFile,false);
AProject.MainFileID:=0;
// create program source
le:=LineEnding;
NewSource:='program FPCUnitProject1;'+le
+le
+'{$mode objfpc}{$H+}'+le
+le
+'uses'+le
+' Interfaces, Forms, GuiTestRunner;'+le
+le
+'begin'+le
+' Application.Initialize;'+le
+' Application.CreateForm(TGuiTestRunner, TestRunner);'+le
+' Application.Run;'+le
+'end.'+le
+le;
AProject.MainFile.SetSourceText(NewSource);
// add
AProject.AddPackageDependency('FCL');
AProject.AddPackageDependency('LCL');
AProject.AddPackageDependency('FPCUnitTestRunner');
end;
procedure TFPCUnitApplicationDescriptor.CreateStartFiles(AProject: TLazProject);
begin
LazarusIDE.DoNewEditorFile(FileDescriptorFPCUnitTestCase,'','',
[nfIsPartOfProject,nfOpenInEditor,nfCreateDefaultSrc]);
end;
{ TFileDescPascalUnitFPCUnitTestCase }
constructor TFileDescPascalUnitFPCUnitTestCase.Create;
begin
inherited Create;
Name:='FPCUnitTestCase';
DefaultFilename:='testcase.pas';
DefaultSourceName:='TestCase1';
end;
function TFileDescPascalUnitFPCUnitTestCase.GetInterfaceUsesSection: string;
begin
Result:=inherited GetInterfaceUsesSection;
Result:=Result+', fpcunit, testutils, testregistry';
end;
function TFileDescPascalUnitFPCUnitTestCase.GetLocalizedName: string;
begin
Result:='FPCUnit Test Case';
end;
function TFileDescPascalUnitFPCUnitTestCase.GetLocalizedDescription: string;
begin
Result:='FPCUnit Test Case'#13
+'A unit containing a FPCUnit Test Case.';
end;
function TFileDescPascalUnitFPCUnitTestCase.GetInterfaceSource(const Filename,
SourceName, ResourceName: string): string;
var
le: string;
TestCaseName: string;
begin
TestCaseName:= 'T'+SourceName;
le:=System.LineEnding;
Result:='type'+le
+' '+TestCaseName+'=class(TTestCase)'+le
+' published'+le
+' procedure TestHookUp;'+le
+' end;'+le+le;
end;
function TFileDescPascalUnitFPCUnitTestCase.GetImplementationSource(
const Filename, SourceName, ResourceName: string): string;
var
le: string;
TestCaseName: string;
begin
TestCaseName:= 'T'+SourceName;
le:=System.LineEnding;
Result:='procedure '+TestCaseName+'.TestHookUp;'+le
+'begin'+le
+' Fail(''Write your own test'');'+le
+'end;'+le
+le
+'Initialization'+le
+le
+' RegisterTest('+TestCaseName+');'
+le;
end;
end.

View File

@ -0,0 +1 @@
Output directory of package fpcunitide

View File

@ -0,0 +1 @@
Output directory of package fpcunittestrunner

View File

@ -23,10 +23,6 @@ SET FPCBINDIR=c:\lazarus\source\fpcbindir
:: it should have the debugger with the name gdb.exe in its bin subdirectory
SET GDBDIR=c:\lazarus\source\mingw
:: Path to the directory containing the mingw gdb debugger installation
:: it should have the debugger with the name gdb.exe in its bin subdirectory
SET GDBDIR=c:\lazarus\source\mingw
:: Path to build directory.
:: In this directory an image of the installation will be built.
SET BUILDDIR=c:\temp\lazbuild