123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531 |
- unit tests.rtti.invoke;
- {$ifdef fpc}
- {$mode objfpc}{$H+}
- {$endif}
- {.$define debug}
- interface
- uses
- {$IFDEF FPC}
- fpcunit,testregistry, testutils,
- {$ELSE FPC}
- TestFramework,
- {$ENDIF FPC}
- sysutils, typinfo, Rtti;
- type
- TTestInvoke = class(TTestCase)
- private type
- TInvokeFlag = (
- ifStatic,
- ifConstructor
- );
- TInvokeFlags = set of TInvokeFlag;
- private
- function DoInvoke(aCodeAddress: CodePointer; aArgs: TValueArray; aCallConv: TCallConv; aResultType: PTypeInfo; aFlags: TInvokeFlags; out aValid: Boolean): TValue;
- procedure DoStaticInvokeTestOrdinalCompare(const aTestName: String; aAddress: CodePointer; aCallConv: TCallConv; aValues: TValueArray; aReturnType: PTypeInfo; aResult: Int64);
- procedure DoStaticInvokeTestAnsiStringCompare(const aTestName: String; aAddress: CodePointer; aCallConv: TCallConv; aValues: TValueArray; aReturnType: PTypeInfo; constref aResult: AnsiString);
- procedure DoStaticInvokeTestUnicodeStringCompare(const aTestName: String; aAddress: CodePointer; aCallConv: TCallConv; aValues: TValueArray; aReturnType: PTypeInfo; constref aResult: UnicodeString);
- {$ifdef fpc}
- procedure Status(const aMsg: String);
- {$endif}
- published
- procedure TestShortString;
- procedure TestAnsiString;
- procedure TestWideString;
- procedure TestUnicodeString;
- procedure TestLongInt;
- procedure TestInt64;
- procedure TestTObject;
- end;
- {$ifndef fpc}
- TValueHelper = record helper for TValue
- function AsUnicodeString: UnicodeString;
- function AsAnsiString: AnsiString;
- end;
- {$endif}
- implementation
- {$ifndef fpc}
- function TValueHelper.AsUnicodeString: UnicodeString;
- begin
- Result := UnicodeString(AsString);
- end;
- function TValueHelper.AsAnsiString: AnsiString;
- begin
- Result := AnsiString(AsString);
- end;
- {$endif}
- function TTestInvoke.DoInvoke(aCodeAddress: CodePointer; aArgs: TValueArray;
- aCallConv: TCallConv; aResultType: PTypeInfo; aFlags: TInvokeFlags; out aValid: Boolean): TValue;
- begin
- try
- Result := Rtti.Invoke(aCodeAddress, aArgs, aCallConv, aResultType, ifStatic in aFlags, ifConstructor in aFlags);
- aValid := True;
- except
- on e: ENotImplemented do begin
- Status('Ignoring unimplemented functionality of test');
- aValid := False;
- end else
- raise;
- end;
- end;
- procedure TTestInvoke.DoStaticInvokeTestOrdinalCompare(const aTestName: String; aAddress: CodePointer; aCallConv: TCallConv; aValues: TValueArray; aReturnType: PTypeInfo; aResult: Int64);
- var
- resval: TValue;
- valid: Boolean;
- begin
- resval := DoInvoke(aAddress, aValues, aCallConv, aReturnType, [ifStatic], valid);
- if valid and Assigned(aReturnType) and (resval.AsOrdinal <> aResult) then begin
- Fail('Result of test "%s" is unexpected; expected: %s, got: %s', [aTestName, IntToStr(aResult), IntToStr(resval.AsOrdinal)]);
- end;
- end;
- procedure TTestInvoke.DoStaticInvokeTestAnsiStringCompare(
- const aTestName: String; aAddress: CodePointer; aCallConv: TCallConv;
- aValues: TValueArray; aReturnType: PTypeInfo; constref aResult: AnsiString);
- var
- resval: TValue;
- valid: Boolean;
- begin
- resval := DoInvoke(aAddress, aValues, aCallConv, aReturnType, [ifStatic], valid);
- if valid and Assigned(aReturnType) and (resval.AsAnsiString <> aResult) then begin
- Fail('Result of test "%s" is unexpected; expected: "%s", got: "%s"', [aTestName, aResult, resval.AsString]);
- end;
- end;
- procedure TTestInvoke.DoStaticInvokeTestUnicodeStringCompare(
- const aTestName: String; aAddress: CodePointer; aCallConv: TCallConv;
- aValues: TValueArray; aReturnType: PTypeInfo; constref aResult: UnicodeString
- );
- var
- resval: TValue;
- valid: Boolean;
- begin
- resval := DoInvoke(aAddress, aValues, aCallConv, aReturnType, [ifStatic], valid);
- if valid and Assigned(aReturnType) and (resval.AsUnicodeString <> aResult) then begin
- Fail('Result of test "%s" is unexpected; expected: "%s", got: "%s"', [aTestName, aResult, resval.AsString]);
- end;
- end;
- {$ifdef fpc}
- procedure TTestInvoke.Status(const aMsg: String);
- begin
- {$ifdef debug}
- Writeln(aMsg);
- {$endif}
- end;
- {$endif}
- function TestShortStringRegister(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: ShortString): ShortString; register;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- function TestShortStringCdecl(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: ShortString): ShortString; cdecl;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- function TestShortStringStdCall(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: ShortString): ShortString; stdcall;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- function TestShortStringPascal(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: ShortString): ShortString; pascal;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- procedure TTestInvoke.TestShortString;
- const
- strs: array[0..5] of ShortString = (
- 'This ',
- 'is a ',
- 'test ',
- 'of ',
- 'shortstring ',
- 'concatenation'
- );
- var
- values: TValueArray;
- resstr: ShortString;
- i: LongInt;
- begin
- SetLength(values, Length(strs));
- resstr := '';
- for i := Low(values) to High(values) do begin
- TValue.Make(@strs[i], TypeInfo(ShortString), values[i]);
- resstr := resstr + strs[i];
- end;
- DoStaticInvokeTestAnsiStringCompare('ShortString Register', @TestShortStringRegister, ccReg, values, TypeInfo(ShortString), resstr);
- DoStaticInvokeTestAnsiStringCompare('ShortString Cdecl', @TestShortStringCdecl, ccCdecl, values, TypeInfo(ShortString), resstr);
- DoStaticInvokeTestAnsiStringCompare('ShortString StdCall', @TestShortStringStdCall, ccStdCall, values, TypeInfo(ShortString), resstr);
- DoStaticInvokeTestAnsiStringCompare('ShortString Pascal', @TestShortStringPascal, ccPascal, values, TypeInfo(ShortString), resstr);
- end;
- function TestAnsiStringRegister(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: AnsiString): AnsiString; register;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- function TestAnsiStringCdecl(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: AnsiString): AnsiString; cdecl;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- function TestAnsiStringStdCall(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: AnsiString): AnsiString; stdcall;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- function TestAnsiStringPascal(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: AnsiString): AnsiString; pascal;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- procedure TTestInvoke.TestAnsiString;
- const
- strs: array[0..5] of AnsiString = (
- 'This ',
- 'is a ',
- 'test ',
- 'of ',
- 'AnsiString ',
- 'concatenation'
- );
- var
- values: TValueArray;
- resstr: AnsiString;
- i: LongInt;
- begin
- SetLength(values, Length(strs));
- resstr := '';
- for i := Low(values) to High(values) do begin
- TValue.Make(@strs[i], TypeInfo(AnsiString), values[i]);
- resstr := resstr + strs[i];
- end;
- DoStaticInvokeTestAnsiStringCompare('AnsiString Register', @TestAnsiStringRegister, ccReg, values, TypeInfo(AnsiString), resstr);
- DoStaticInvokeTestAnsiStringCompare('AnsiString Cdecl', @TestAnsiStringCdecl, ccCdecl, values, TypeInfo(AnsiString), resstr);
- DoStaticInvokeTestAnsiStringCompare('AnsiString StdCall', @TestAnsiStringStdCall, ccStdCall, values, TypeInfo(AnsiString), resstr);
- DoStaticInvokeTestAnsiStringCompare('AnsiString Pascal', @TestAnsiStringPascal, ccPascal, values, TypeInfo(AnsiString), resstr);
- end;
- function TestWideStringRegister(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: WideString): WideString; register;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- function TestWideStringCdecl(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: WideString): WideString; cdecl;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- function TestWideStringStdCall(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: WideString): WideString; stdcall;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- function TestWideStringPascal(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: WideString): WideString; pascal;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- procedure TTestInvoke.TestWideString;
- const
- strs: array[0..5] of WideString = (
- 'This ',
- 'is a ',
- 'test ',
- 'of ',
- 'WideString ',
- 'concatenation'
- );
- var
- values: TValueArray;
- resstr: WideString;
- i: LongInt;
- begin
- SetLength(values, Length(strs));
- resstr := '';
- for i := Low(values) to High(values) do begin
- TValue.Make(@strs[i], TypeInfo(WideString), values[i]);
- resstr := resstr + strs[i];
- end;
- DoStaticInvokeTestUnicodeStringCompare('WideString Register', @TestWideStringRegister, ccReg, values, TypeInfo(WideString), resstr);
- DoStaticInvokeTestUnicodeStringCompare('WideString Cdecl', @TestWideStringCdecl, ccCdecl, values, TypeInfo(WideString), resstr);
- DoStaticInvokeTestUnicodeStringCompare('WideString StdCall', @TestWideStringStdCall, ccStdCall, values, TypeInfo(WideString), resstr);
- DoStaticInvokeTestUnicodeStringCompare('WideString Pascal', @TestWideStringPascal, ccPascal, values, TypeInfo(WideString), resstr);
- end;
- function TestUnicodeStringRegister(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: UnicodeString): UnicodeString; register;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- function TestUnicodeStringCdecl(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: UnicodeString): UnicodeString; cdecl;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- function TestUnicodeStringStdCall(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: UnicodeString): UnicodeString; stdcall;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- function TestUnicodeStringPascal(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: UnicodeString): UnicodeString; pascal;
- begin
- Result := aArg1 + aArg2 + aArg3 + aArg4 + aArg5 + aArg6;
- end;
- procedure TTestInvoke.TestUnicodeString;
- const
- strs: array[0..5] of UnicodeString = (
- 'This ',
- 'is a ',
- 'test ',
- 'of ',
- 'UnicodeString ',
- 'concatenation'
- );
- var
- values: TValueArray;
- resstr: UnicodeString;
- i: LongInt;
- begin
- SetLength(values, Length(strs));
- resstr := '';
- for i := Low(values) to High(values) do begin
- TValue.Make(@strs[i], TypeInfo(UnicodeString), values[i]);
- resstr := resstr + strs[i];
- end;
- DoStaticInvokeTestUnicodeStringCompare('UnicodeString Register', @TestUnicodeStringRegister, ccReg, values, TypeInfo(UnicodeString), resstr);
- DoStaticInvokeTestUnicodeStringCompare('UnicodeString Cdecl', @TestUnicodeStringCdecl, ccCdecl, values, TypeInfo(UnicodeString), resstr);
- DoStaticInvokeTestUnicodeStringCompare('UnicodeString StdCall', @TestUnicodeStringStdCall, ccStdCall, values, TypeInfo(UnicodeString), resstr);
- DoStaticInvokeTestUnicodeStringCompare('UnicodeString Pascal', @TestUnicodeStringPascal, ccPascal, values, TypeInfo(UnicodeString), resstr);
- end;
- function TestLongIntRegister(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: LongInt): LongInt; register;
- begin
- Result := aArg1 + aArg2 * 10 + aArg3 * 100 + aArg4 * 1000 + aArg5 * 10000 + aArg6 * 100000;
- end;
- function TestLongIntCdecl(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: LongInt): LongInt; cdecl;
- begin
- Result := aArg1 + aArg2 * 10 + aArg3 * 100 + aArg4 * 1000 + aArg5 * 10000 + aArg6 * 100000;
- end;
- function TestLongIntStdCall(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: LongInt): LongInt; stdcall;
- begin
- Result := aArg1 + aArg2 * 10 + aArg3 * 100 + aArg4 * 1000 + aArg5 * 10000 + aArg6 * 100000;
- end;
- function TestLongIntPascal(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: LongInt): LongInt; pascal;
- begin
- Result := aArg1 + aArg2 * 10 + aArg3 * 100 + aArg4 * 1000 + aArg5 * 10000 + aArg6 * 100000;
- end;
- procedure TTestInvoke.TestLongInt;
- const
- vals: array[0..5] of LongInt = (
- 8,
- 4,
- 7,
- 3,
- 6,
- 1
- );
- var
- values: TValueArray;
- resval, factor: LongInt;
- i: LongInt;
- begin
- SetLength(values, Length(vals));
- resval := 0;
- factor := 1;
- for i := Low(values) to High(values) do begin
- TValue.Make(@vals[i], TypeInfo(LongInt), values[i]);
- resval := resval + vals[i] * factor;
- factor := factor * 10;
- end;
- DoStaticInvokeTestOrdinalCompare('LongInt Register', @TestLongIntRegister, ccReg, values, TypeInfo(LongInt), resval);
- DoStaticInvokeTestOrdinalCompare('LongInt Cdecl', @TestLongIntCdecl, ccCdecl, values, TypeInfo(LongInt), resval);
- DoStaticInvokeTestOrdinalCompare('LongInt StdCall', @TestLongIntStdCall, ccStdCall, values, TypeInfo(LongInt), resval);
- DoStaticInvokeTestOrdinalCompare('LongInt Pascal', @TestLongIntPascal, ccPascal, values, TypeInfo(LongInt), resval);
- end;
- function TestInt64Register(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: Int64): Int64; register;
- begin
- Result := aArg1 + aArg2 * 100 + aArg3 * 10000 + aArg4 * 1000000 + aArg5 * 100000000 + aArg6 * 10000000000;
- end;
- function TestInt64Cdecl(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: Int64): Int64; cdecl;
- begin
- Result := aArg1 + aArg2 * 100 + aArg3 * 10000 + aArg4 * 1000000 + aArg5 * 100000000 + aArg6 * 10000000000;
- end;
- function TestInt64StdCall(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: Int64): Int64; stdcall;
- begin
- Result := aArg1 + aArg2 * 100 + aArg3 * 10000 + aArg4 * 1000000 + aArg5 * 100000000 + aArg6 * 10000000000;
- end;
- function TestInt64Pascal(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: Int64): Int64; pascal;
- begin
- Result := aArg1 + aArg2 * 100 + aArg3 * 10000 + aArg4 * 1000000 + aArg5 * 100000000 + aArg6 * 10000000000;
- end;
- procedure TTestInvoke.TestInt64;
- const
- vals: array[0..5] of Int64 = (
- 8,
- 4,
- 7,
- 3,
- 6,
- 1
- );
- var
- values: TValueArray;
- resval, factor: Int64;
- i: LongInt;
- begin
- SetLength(values, Length(vals));
- resval := 0;
- factor := 1;
- for i := Low(values) to High(values) do begin
- TValue.Make(@vals[i], TypeInfo(Int64), values[i]);
- resval := resval + vals[i] * factor;
- factor := factor * 100;
- end;
- DoStaticInvokeTestOrdinalCompare('Int64 Register', @TestInt64Register, ccReg, values, TypeInfo(Int64), resval);
- DoStaticInvokeTestOrdinalCompare('Int64 Cdecl', @TestInt64Cdecl, ccCdecl, values, TypeInfo(Int64), resval);
- DoStaticInvokeTestOrdinalCompare('Int64 StdCall', @TestInt64StdCall, ccStdCall, values, TypeInfo(Int64), resval);
- DoStaticInvokeTestOrdinalCompare('Int64 Pascal', @TestInt64Pascal, ccPascal, values, TypeInfo(Int64), resval);
- end;
- type
- TTestClass = class
- fString: String;
- fValue: LongInt;
- end;
- function TestTTestClassRegister(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: TTestClass): TTestClass; register;
- begin
- Result := TTestClass.Create;
- Result.fString := aArg1.fString + aArg2.fString + aArg3.fString + aArg4.fString + aArg5.fString + aArg6.fString;
- Result.fValue := aArg1.fValue + aArg2.fValue * 10 + aArg3.fValue * 100 + aArg4.fValue * 1000 + aArg5.fValue * 10000 + aArg6.fValue * 100000;
- end;
- function TestTTestClassCdecl(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: TTestClass): TTestClass; cdecl;
- begin
- Result := TTestClass.Create;
- Result.fString := aArg1.fString + aArg2.fString + aArg3.fString + aArg4.fString + aArg5.fString + aArg6.fString;
- Result.fValue := aArg1.fValue + aArg2.fValue * 10 + aArg3.fValue * 100 + aArg4.fValue * 1000 + aArg5.fValue * 10000 + aArg6.fValue * 100000;
- end;
- function TestTTestClassStdCall(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: TTestClass): TTestClass; stdcall;
- begin
- Result := TTestClass.Create;
- Result.fString := aArg1.fString + aArg2.fString + aArg3.fString + aArg4.fString + aArg5.fString + aArg6.fString;
- Result.fValue := aArg1.fValue + aArg2.fValue * 10 + aArg3.fValue * 100 + aArg4.fValue * 1000 + aArg5.fValue * 10000 + aArg6.fValue * 100000;
- end;
- function TestTTestClassPascal(aArg1, aArg2, aArg3, aArg4, aArg5, aArg6: TTestClass): TTestClass; pascal;
- begin
- Result := TTestClass.Create;
- Result.fString := aArg1.fString + aArg2.fString + aArg3.fString + aArg4.fString + aArg5.fString + aArg6.fString;
- Result.fValue := aArg1.fValue + aArg2.fValue * 10 + aArg3.fValue * 100 + aArg4.fValue * 1000 + aArg5.fValue * 10000 + aArg6.fValue * 100000;
- end;
- procedure TTestInvoke.TestTObject;
- procedure DoStaticInvokeTestClassCompare(
- const aTestName: String; aAddress: CodePointer; aCallConv: TCallConv;
- aValues: TValueArray; aReturnType: PTypeInfo; aResult: TTestClass
- );
- var
- resval: TValue;
- rescls: TTestClass;
- valid: Boolean;
- begin
- resval := DoInvoke(aAddress, aValues, aCallConv, aReturnType, [ifStatic], valid);
- if valid and Assigned(aReturnType) then begin
- rescls := TTestClass(PPointer(resval.GetReferenceToRawData)^);
- if (rescls.fString <> aResult.fString) or (rescls.fValue <> aResult.fValue) then
- Fail('Result of test "%s" is unexpected; expected: "%s"/%s, got: "%s"/%s', [aTestName, aResult.fString, IntToStr(aResult.fValue), rescls.fString, IntToStr(rescls.fValue)]);
- end;
- end;
- const
- strs: array[0..5] of AnsiString = (
- 'This ',
- 'is a ',
- 'test ',
- 'of ',
- 'AnsiString ',
- 'concatenation'
- );
- vals: array[0..5] of Int64 = (
- 8,
- 4,
- 7,
- 3,
- 6,
- 1
- );
- var
- values: TValueArray;
- t, rescls: TTestClass;
- i, factor: LongInt;
- begin
- SetLength(values, Length(vals));
- factor := 1;
- rescls := TTestClass.Create;
- for i := Low(values) to High(values) do begin
- t := TTestClass.Create;
- t.fString := strs[i];
- t.fValue := vals[i];
- TValue.Make(@t, TypeInfo(TTestClass), values[i]);
- rescls.fValue := rescls.fValue + vals[i] * factor;
- rescls.fString := rescls.fString + strs[i];
- factor := factor * 10;
- end;
- DoStaticInvokeTestClassCompare('TTestClass Register', @TestTTestClassRegister, ccReg, values, TypeInfo(TTestClass), rescls);
- DoStaticInvokeTestClassCompare('TTestClass Cdecl', @TestTTestClassCdecl, ccCdecl, values, TypeInfo(TTestClass), rescls);
- DoStaticInvokeTestClassCompare('TTestClass StdCall', @TestTTestClassStdCall, ccStdCall, values, TypeInfo(TTestClass), rescls);
- DoStaticInvokeTestClassCompare('TTestClass Pascal', @TestTTestClassPascal, ccPascal, values, TypeInfo(TTestClass), rescls);
- end;
- begin
- {$ifdef fpc}
- RegisterTest(TTestInvoke);
- {$else fpc}
- RegisterTest(TTestInvoke.Suite);
- {$endif fpc}
- end.
|