Add tests for generic functions/procedures/methods

git-svn-id: trunk@32440 -
This commit is contained in:
svenbarth 2015-11-21 16:53:11 +00:00
parent c81eda7a42
commit 1d72397c19
17 changed files with 479 additions and 0 deletions

16
.gitattributes vendored
View File

@ -12242,6 +12242,21 @@ tests/test/tgeneric96.pp svneol=native#text/pascal
tests/test/tgeneric97.pp svneol=native#text/pascal
tests/test/tgeneric98.pp svneol=native#text/pascal
tests/test/tgeneric99.pp svneol=native#text/pascal
tests/test/tgenfunc1.pp svneol=native#text/pascal
tests/test/tgenfunc10.pp svneol=native#text/pascal
tests/test/tgenfunc11.pp svneol=native#text/pascal
tests/test/tgenfunc12.pp svneol=native#text/pascal
tests/test/tgenfunc13.pp svneol=native#text/pascal
tests/test/tgenfunc14.pp svneol=native#text/pascal
tests/test/tgenfunc15.pp svneol=native#text/pascal
tests/test/tgenfunc2.pp svneol=native#text/pascal
tests/test/tgenfunc3.pp svneol=native#text/pascal
tests/test/tgenfunc4.pp svneol=native#text/pascal
tests/test/tgenfunc5.pp svneol=native#text/pascal
tests/test/tgenfunc6.pp svneol=native#text/pascal
tests/test/tgenfunc7.pp svneol=native#text/pascal
tests/test/tgenfunc8.pp svneol=native#text/pascal
tests/test/tgenfunc9.pp svneol=native#text/pascal
tests/test/tgoto.pp svneol=native#text/plain
tests/test/theap.pp svneol=native#text/plain
tests/test/theapthread.pp svneol=native#text/plain
@ -12896,6 +12911,7 @@ tests/test/ugeneric96b.pp svneol=native#text/pascal
tests/test/ugeneric96c.pp svneol=native#text/pascal
tests/test/ugeneric96d.pp svneol=native#text/pascal
tests/test/ugeneric99.pp svneol=native#text/pascal
tests/test/ugenfunc7.pp svneol=native#text/pascal
tests/test/uhintdir.pp svneol=native#text/plain
tests/test/uhlp3.pp svneol=native#text/pascal
tests/test/uhlp31.pp svneol=native#text/pascal

17
tests/test/tgenfunc1.pp Normal file
View File

@ -0,0 +1,17 @@
{ test syntax of a global generic function in mode objfpc }
program tgenfunc1;
{$mode objfpc}
generic function Add<T>(aLeft, aRight: T): T;
begin
Result := aLeft + aRight;
end;
begin
if specialize Add<LongInt>(2, 3) <> 5 then
Halt(1);
if specialize Add<String>('Hello', 'World') <> 'HelloWorld' then
Halt(2);
end.

50
tests/test/tgenfunc10.pp Normal file
View File

@ -0,0 +1,50 @@
{ %NORUN }
{ ensure that specializations with local types are handled correctly }
program tgenfunc10;
{$mode objfpc}
operator := (aOther: LongInt): String;
begin
Str(aOther, Result);
end;
generic function Test<T>(aArg: T): String;
begin
Result := aArg.Test;
end;
procedure Test1;
type
TTest = record
Test: LongInt;
end;
var
s: String;
t: TTest;
begin
t.Test := 42;
s := specialize Test<TTest>(t);
end;
procedure Test2;
type
TTest = record
Test: String;
end;
var
s: String;
t: TTest;
begin
t.Test := 'Hello World';
s := specialize Test<TTest>(t);
end;
begin
Test1;
Test2;
end.

18
tests/test/tgenfunc11.pp Normal file
View File

@ -0,0 +1,18 @@
{ %FAIL }
program tgenfunc11;
{$mode objfpc}
type
TTest = class
generic procedure Test<T>; virtual;
end;
generic procedure TTest.Test<T>;
begin
end;
begin
end.

26
tests/test/tgenfunc12.pp Normal file
View File

@ -0,0 +1,26 @@
program tgenfunc12;
{$mode objfpc}
type
TTest = class
generic function Test<T: class>: T;
end;
generic function TTest.Test<T>: T;
begin
Result := T.Create;
end;
generic function Test<T: IInterface>: T;
begin
Result := TInterfacedObject.Create;
end;
var
t: TTest;
begin
t := TTest.Create;
t.specialize Test<TObject>.Free;
specialize Test<IInterface>;
end.

21
tests/test/tgenfunc13.pp Normal file
View File

@ -0,0 +1,21 @@
{ %FAIL }
{ constraints must not be repeated in the definition }
program tgenfunc13;
{$mode objfpc}
type
TTest = class
generic procedure Test<T: class>;
end;
generic procedure TTest.Test<T: class>;
begin
end;
begin
end.

21
tests/test/tgenfunc14.pp Normal file
View File

@ -0,0 +1,21 @@
{ %FAIL }
unit tgenfunc14;
{$mode objfpc}
{ constraints must not be repeated in the definition }
interface
generic procedure Test<T: class>;
implementation
generic procedure Test<T: class>;
begin
end;
end.

45
tests/test/tgenfunc15.pp Normal file
View File

@ -0,0 +1,45 @@
{ correct match functions with array parameters of the generic type }
unit tgenfunc15;
{$mode objfpc}{$H+}
interface
type
generic TStaticArray<T> = array[0..4] of T;
TTest = class
generic procedure Test<T>(aArg1: T; aArg2: array of T; aArg3: specialize TStaticArray<T>);
generic procedure Test<T>(aArg1: T; aArg2: array of T; aArg3: specialize TStaticArray<T>; aArg4: LongInt);
end;
generic procedure Test<T>(aArg1: T; aArg2: array of T; aArg3: specialize TStaticArray<T>);
generic procedure Test<T>(aArg1: T; aArg2: array of T; aArg3: specialize TStaticArray<T>; aArg4: LongInt);
implementation
generic procedure Test<T>(aArg1: T; aArg2: array of T; aArg3: specialize TStaticArray<T>);
begin
end;
generic procedure Test<T>(aArg1: T; aArg2: array of T; aArg3: specialize TStaticArray<T>; aArg4: LongInt);
begin
end;
generic procedure TTest.Test<T>(aArg1: T; aArg2: array of T; aArg3: specialize TStaticArray<T>);
begin
end;
generic procedure TTest.Test<T>(aArg1: T; aArg2: array of T; aArg3: specialize TStaticArray<T>; aArg4: LongInt);
begin
end;
var
t: array[0..4] of LongInt = (0, 1, 2, 3, 4);
s: array[0..4] of String = ('abc', 'def', 'ghi', 'jkl', 'mno');
initialization
specialize Test<LongInt>(42, [32, 43], t);
specialize Test<String>('FPC', ['Hello', 'World'], s, 42);
end.

17
tests/test/tgenfunc2.pp Normal file
View File

@ -0,0 +1,17 @@
{ test syntax of a global generic function in mode delphi }
program tgenfunc2;
{$mode delphi}
function Add<T>(aLeft, aRight: T): T;
begin
Result := aLeft + aRight;
end;
begin
if Add<LongInt>(2, 3) <> 5 then
Halt(1);
if Add<String>('Hello', 'World') <> 'HelloWorld' then
Halt(2);
end.

22
tests/test/tgenfunc3.pp Normal file
View File

@ -0,0 +1,22 @@
{ test syntax of a generic class function in mode objfpc }
program tgenfunc3;
{$mode objfpc}
type
TTest = class
generic class function Add<T>(aLeft, aRight: T): T;
end;
generic class function TTest.Add<T>(aLeft, aRight: T): T;
begin
Result := aLeft + aRight;
end;
begin
if TTest.specialize Add<LongInt>(2, 3) <> 5 then
Halt(1);
if TTest.specialize Add<String>('Hello', 'World') <> 'HelloWorld' then
Halt(2);
end.

22
tests/test/tgenfunc4.pp Normal file
View File

@ -0,0 +1,22 @@
{ test syntax of a generic class function in mode delphi }
program tgenfunc4;
{$mode delphi}
type
TTest = class
class function Add<T>(aLeft, aRight: T): T;
end;
class function TTest.Add<T>(aLeft, aRight: T): T;
begin
Result := aLeft + aRight;
end;
begin
if TTest.Add<LongInt>(2, 3) <> 5 then
Halt(1);
if TTest.Add<String>('Hello', 'World') <> 'HelloWorld' then
Halt(2);
end.

24
tests/test/tgenfunc5.pp Normal file
View File

@ -0,0 +1,24 @@
{ test syntax of a generic method in mode objfpc }
program tgenfunc5;
{$mode objfpc}
type
TTest = class
generic function Add<T>(aLeft, aRight: T): T;
end;
generic function TTest.Add<T>(aLeft, aRight: T): T;
begin
Result := aLeft + aRight;
end;
var
t: TTest;
begin
if t.specialize Add<LongInt>(2, 3) <> 5 then
Halt(1);
if t.specialize Add<String>('Hello', 'World') <> 'HelloWorld' then
Halt(2);
end.

24
tests/test/tgenfunc6.pp Normal file
View File

@ -0,0 +1,24 @@
{ test syntax of a generic method in mode delphi }
program tgenfunc6;
{$mode delphi}
type
TTest = class
function Add<T>(aLeft, aRight: T): T;
end;
function TTest.Add<T>(aLeft, aRight: T): T;
begin
Result := aLeft + aRight;
end;
var
t: TTest;
begin
if t.Add<LongInt>(2, 3) <> 5 then
Halt(1);
if t.Add<String>('Hello', 'World') <> 'HelloWorld' then
Halt(2);
end.

26
tests/test/tgenfunc7.pp Normal file
View File

@ -0,0 +1,26 @@
{ generics in another unit work as well }
program tgenfunc7;
{$mode objfpc}
uses
ugenfunc7;
var
t: TTest;
begin
if specialize Add<LongInt>(3, 4) <> 7 then
Halt(1);
if specialize Add<String>('Hello', 'World') <> 'HelloWorld' then
Halt(2);
if TTest.specialize AddClass<LongInt>(3, 4) <> 7 then
Halt(3);
if TTest.specialize AddClass<String>('Hello', 'World') <> 'HelloWorld' then
Halt(4);
if t.specialize Add<LongInt>(3, 4) <> 7 then
Halt(5);
if t.specialize Add<String>('Hello', 'World') <> 'HelloWorld' then
Halt(6);
end.

42
tests/test/tgenfunc8.pp Normal file
View File

@ -0,0 +1,42 @@
{ %NORUN }
{ overloads with other generic functions work correctly }
program tgenfunc8;
{$mode objfpc}
operator := (aOther: LongInt): String;
begin
Str(aOther, Result);
end;
operator := (aOther: String): LongInt;
var
code: LongInt;
begin
Val(aOther, Result, code);
end;
generic function Add<T>(aLeft, aRight: T): T;
begin
Result := aLeft + aRight;
end;
generic function Add<S, T>(aLeft, aRight: S): T;
begin
Result := aLeft + aRight;
end;
generic function Add<T>(aLeft: T): T;
begin
Result := aLeft + aLeft;
end;
begin
Writeln(specialize Add<LongInt>(4, 5));
Writeln(specialize Add<LongInt, String>(3, 8));
Writeln(specialize Add<String, LongInt>('3', '8'));
Writeln(specialize Add<LongInt>(2));
Writeln(specialize Add<String>('Test'));
end.

14
tests/test/tgenfunc9.pp Normal file
View File

@ -0,0 +1,14 @@
program tgenfunc9;
uses
ugenfunc7;
var
t: TTest;
begin
t := TTest.Create;
Writeln(t.specialize GetStrictPrivate<LongInt>);
Writeln(t.specialize GetPrivate<LongInt>);
Writeln(t.specialize GetStrictProtected<LongInt>);
Writeln(t.specialize GetProtected<LongInt>);
end.

74
tests/test/ugenfunc7.pp Normal file
View File

@ -0,0 +1,74 @@
unit ugenfunc7;
{$mode objfpc}
interface
type
TTest = class
constructor Create;
generic function Add<T>(aLeft, aRight: T): T;
generic class function AddClass<T>(aLeft, aRight: T): T;
generic function GetPrivate<T>: T;
generic function GetProtected<T>: T;
generic function GetStrictPrivate<T>: T;
generic function GetStrictProtected<T>: T;
strict private
fStrictPrivate: LongInt;
private
fPrivate: LongInt;
strict protected
fStrictProtected: LongInt;
protected
fProtected: LongInt;
end;
generic function Add<T>(aLeft, aRight: T): T;
implementation
constructor TTest.Create;
begin
fStrictPrivate := 1;
fPrivate := 2;
fStrictProtected := 3;
fProtected := 4;
end;
generic function TTest.Add<T>(aLeft, aRight: T): T;
begin
Result := aLeft + aRight;
end;
generic class function TTest.AddClass<T>(aLeft, aRight: T): T;
begin
Result := aLeft + aRight;
end;
generic function TTest.GetStrictPrivate<T>: T;
begin
Result := fStrictPrivate;
end;
generic function TTest.GetPrivate<T>: T;
begin
Result := fPrivate;
end;
generic function TTest.GetStrictProtected<T>: T;
begin
Result := fStrictProtected;
end;
generic function TTest.GetProtected<T>: T;
begin
Result := fProtected;
end;
generic function Add<T>(aLeft, aRight: T): T;
begin
Result := aLeft + aRight;
end;
end.