lazarus/components/codetools/tests/testmethodjumptool.pas
mattias 512b7c6179 codetools: test JumpToMethod methods
git-svn-id: trunk@56522 -
2017-11-28 13:27:41 +00:00

259 lines
7.4 KiB
ObjectPascal

{
Test with:
./runtests --format=plain --suite=TTestMethodJumpTool
./runtests --format=plain --suite=TestFindJumpPointIncFilewithIntfAndImpl
}
unit TestMethodJumpTool;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, fpcunit, testregistry, LazLoggerBase,
CodeToolManager, StdCodeTools, CodeCache, LinkScanner, TestPascalParser;
type
{ TBaseTestMethodJumpTool }
TBaseTestMethodJumpTool = class(TCustomTestPascalParser)
protected
procedure GetCTMarker(aCode: TCodeBuffer; Comment: string; out Position: TPoint;
LeftOfComment: boolean = true);
function GetInfo(aCode: TCodeBuffer; XY: TPoint): string;
procedure TestJumpToMethod(FromMarker: string; LeftFrom: boolean;
ToMarker: string; LeftTo: boolean; ToColOffset: integer = 0);
end;
{ TTestMethodJumpTool }
TTestMethodJumpTool = class(TBaseTestMethodJumpTool)
published
procedure TestFindJumpPointIncFilewithIntfAndImpl;
procedure TestMethodJump_IntfToImplSingleProc;
procedure TestMethodJump_IntfToImplSingleProcWrongName;
procedure TestMethodJump_IntfToImplSingleProcWrongParam;
procedure TestMethodJump_SingleMethod;
procedure TestMethodJump_MultiMethodWrongName;
end;
implementation
{ TBaseTestMethodJumpTool }
procedure TBaseTestMethodJumpTool.GetCTMarker(aCode: TCodeBuffer; Comment: string;
out Position: TPoint; LeftOfComment: boolean);
var
p: SizeInt;
begin
Position:=Point(0,0);
if Comment[1]<>'{' then
Comment:='{'+Comment+'}';
p:=System.Pos(Comment,aCode.Source);
if p<1 then begin
WriteSource(CodeXYPosition(1,1,Code));
Fail('TTestMethodJumpTool.GetCTMarker, missing marker "'+Comment+'" in "'+Code.Filename+'"');
end;
if not LeftOfComment then
inc(p,length(Comment));
aCode.AbsoluteToLineCol(p,Position.Y,Position.X);
if Position.Y<1 then begin
WriteSource(CodeXYPosition(Position.X,Position.Y,Code));
Fail('TTestMethodJumpTool.GetCTMarker, Code.AbsoluteToLineCol: "'+Comment+'" Pos='+dbgs(Position)+' in "'+Code.Filename+'"');
end;
end;
function TBaseTestMethodJumpTool.GetInfo(aCode: TCodeBuffer; XY: TPoint): string;
var
Line: String;
begin
Line:=aCode.GetLine(XY.Y-1);
Result:=dbgs(XY)+': '+copy(Line,1,XY.X-1)+'|'+copy(Line,XY.X,length(Line));
end;
procedure TBaseTestMethodJumpTool.TestJumpToMethod(FromMarker: string;
LeftFrom: boolean; ToMarker: string; LeftTo: boolean; ToColOffset: integer);
var
FromPos, ToPos: TPoint;
NewCode: TCodeBuffer;
NewX, NewY, NewTopLine, BlockTopLine, BlockBottomLine: integer;
RevertableJump: boolean;
begin
GetCTMarker(Code,FromMarker,FromPos,LeftFrom);
GetCTMarker(Code,ToMarker,ToPos,LeftTo);
inc(ToPos.X,ToColOffset);
if not CodeToolBoss.JumpToMethod(Code,FromPos.X,FromPos.Y,NewCode, NewX, NewY,
NewTopLine, BlockTopLine, BlockBottomLine, RevertableJump) then begin
WriteSource(CodeXYPosition(FromPos.X,FromPos.Y,Code));
Fail('CodeToolBoss.JumpToMethod failed, From line='+IntToStr(FromPos.Y)+' col='+IntToStr(FromPos.X));
end;
if NewCode<>Code then begin
WriteSource(CodeXYPosition(FromPos.X,FromPos.Y,Code));
AssertEquals('JumpToMethod jumped to wrong file, From line='+IntToStr(FromPos.Y)+' col='+IntToStr(FromPos.X),
Code.Filename,NewCode.Filename);
end;
if NewY<>ToPos.Y then begin
WriteSource(CodeXYPosition(ToPos.X,ToPos.Y,Code));
AssertEquals('JumpToMethod jumped to wrong line, From line='+IntToStr(FromPos.Y)+' col='+IntToStr(FromPos.X),
ToPos.Y,NewY);
end;
if NewX<>ToPos.X then begin
WriteSource(CodeXYPosition(ToPos.X,ToPos.Y,Code));
AssertEquals('JumpToMethod jumped to wrong line, From line='+IntToStr(FromPos.Y)+' col='+IntToStr(FromPos.X),
ToPos.X,NewX);
end;
end;
{ TTestMethodJumpTool }
procedure TTestMethodJumpTool.TestFindJumpPointIncFilewithIntfAndImpl;
procedure Test(aTitle: string; Code: TCodeBuffer;
StartMarker: string; LeftOfStart: boolean;
EndMarker: string; LeftOfEnd: boolean);
var
BlockStart: TPoint;
BlockEnd: TPoint;
NewCode: TCodeBuffer;
NewX: integer;
NewY: integer;
NewTopline, BlockTopLine, BlockBottomLine: integer;
RevertableJump: boolean;
begin
GetCTMarker(Code,StartMarker,BlockStart,LeftOfStart);
GetCTMarker(Code,EndMarker,BlockEnd,LeftOfEnd);
//debugln(['TTestCTStdCodetools.TestCTStdFindBlockStart BlockStart=',GetInfo(BlockStart),' BlockEnd=',GetInfo(BlockEnd)]);
if not CodeToolBoss.JumpToMethod(Code,BlockStart.X,BlockStart.Y,
NewCode,NewX,NewY,NewTopline,BlockTopLine,BlockBottomLine,RevertableJump)
then
AssertEquals(aTitle+': '+CodeToolBoss.ErrorMessage,true,false)
else
AssertEquals(aTitle,GetInfo(Code,BlockEnd),GetInfo(NewCode,Point(NewX,NewY)))
end;
var
IncCode: TCodeBuffer;
begin
Code.Source:=''
+'unit Test1;'+LineEnding
+'interface'+LineEnding
+'{$DEFINE UseInterface}'
+'{$I TestMethodJumpTool2.inc}'+LineEnding
+'{$UNDEF UseInterface}'+LineEnding
+'implementation'+LineEnding
+'{$DEFINE UseImplementation}'
+'{$I TestMethodJumpTool2.inc}'+LineEnding
+'end.'+LineEnding;
IncCode:=CodeToolBoss.CreateFile('TestMethodJumpTool2.inc');
IncCode.Source:=''
+'{%MainUnit test1.pas}'+LineEnding
+'{$IFDEF UseInterface}'+LineEnding
+'procedure {ProcHeader}DoSomething;'+LineEnding
+'{$ENDIF}'+LineEnding
+'{$IFDEF UseImplementation}'+LineEnding
+'procedure DoSomething;'+LineEnding
+'begin'+LineEnding
+' {ProcBody}writeln;'+LineEnding
+'end;'+LineEnding
+'{$ENDIF}'+LineEnding;
Test('Method jump from interface to implementation in one include file',
IncCode,'ProcHeader',false,'ProcBody',true);
Test('Method jump from implementation to interface in one include file',
IncCode,'ProcBody',false,'ProcHeader',false);
end;
procedure TTestMethodJumpTool.TestMethodJump_IntfToImplSingleProc;
begin
Add([
'unit Test1;',
'{$mode objfpc}{$H+}',
'interface',
'procedure {a}DoIt;',
'implementation',
'procedure DoIt;',
'begin',
' {b}',
'end;',
'end.']);
TestJumpToMethod('a',false,'b',true);
end;
procedure TTestMethodJumpTool.TestMethodJump_IntfToImplSingleProcWrongName;
begin
Add([
'unit Test1;',
'{$mode objfpc}{$H+}',
'interface',
'procedure {a}DoIt;',
'implementation',
'procedure {b}Do2It;',
'begin',
'end;',
'end.']);
TestJumpToMethod('a',false,'b',false,2);
end;
procedure TTestMethodJumpTool.TestMethodJump_IntfToImplSingleProcWrongParam;
begin
Add([
'unit Test1;',
'{$mode objfpc}{$H+}',
'interface',
'procedure {a}DoIt(s: string);',
'implementation',
'procedure DoIt(s: {b}ansistring);',
'begin',
'end;',
'end.']);
TestJumpToMethod('a',false,'b',false);
end;
procedure TTestMethodJumpTool.TestMethodJump_SingleMethod;
begin
Add([
'unit Test1;',
'{$mode objfpc}{$H+}',
'interface',
'type',
' TBird = class',
' procedure {a}DoIt(s: string);',
' end;',
'implementation',
'procedure TBird.DoIt(s: string);',
'begin',
' {b}',
'end;',
'end.']);
TestJumpToMethod('a',false,'b',true);
end;
procedure TTestMethodJumpTool.TestMethodJump_MultiMethodWrongName;
begin
Add([
'unit Test1;',
'{$mode objfpc}{$H+}',
'interface',
'type',
' TBird = class',
' procedure {a}DoIt(s: string);',
' procedure DoIt;',
' end;',
'implementation',
'procedure TBird.{b}Do2It(s: string);',
'begin',
'end;',
'procedure TBird.DoIt;',
'begin',
'end;',
'end.']);
TestJumpToMethod('a',false,'b',false,2);
end;
initialization
RegisterTest(TTestMethodJumpTool);
end.