delphimvcframework/samples/serversideviews_lua/lua4delphi/unittests/TestLuaWrapper.pas
2021-12-30 10:21:38 +01:00

580 lines
16 KiB
ObjectPascal
Raw Blame History

unit TestLuaWrapper;
{
Delphi DUnit Test Case
----------------------
This unit contains a skeleton test case class generated by the Test Case Wizard.
Modify the generated code to correctly setup and call the methods from the unit
being tested.
}
{ .$RTTI EXPLICIT METHODS([vcPublished, vcPublic]) }
interface
uses
TestFramework,
System.Classes,
LuaBind.Intf,
LuaBind,
System.Rtti,
System.SysUtils;
type
// Test methods for class TLuaEngine
TestTLuaEngine = class(TTestCase)
strict private
FLuaEngine: TLuaEngine;
private
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestLoadScript;
procedure TestLoadScript1;
procedure TestLoadFromFile;
procedure TestDeclareGlobalNil;
procedure TestDeclareGlobalNumber;
procedure TestDeclareGlobalInteger;
procedure TestDeclareGlobalString;
procedure TestDeclareGlobalBoolean;
procedure TestDeclareGlobalLightUserData;
procedure TestDeclareGlobalUserData;
/// /////
procedure TestDeclareGlobalFunction;
procedure TestGetGlobal;
/// ///test core extensions
procedure TestExposeDataSet;
procedure TestExposeDelphiObject;
procedure TestExposeDelphiObjectNoDeps;
procedure TestExposeVCLDelphiObject;
procedure TestExposeVCLDelphiObjectSetProperty;
procedure TestCreateDelphiObject;
procedure TestCreateDelphiObjectWithWringConstructor;
/// ///// test helper pusher
procedure TestPushTableWithIntegerKeys;
procedure TestPushTableWithStringKeys;
procedure TestPushTableWithTValueValues;
procedure TestPushTableFromCompoundObject;
/// ////
procedure TestExecuteFunction;
procedure TestMyDirtyTests;
end;
implementation
uses
System.IOUtils,
LuaBind.CustomType.DataSet,
Datasnap.DBClient,
LuaBind.CustomType.PODO,
LuaBind.CustomType.UserType,
System.Generics.Collections,
TestObjects;
procedure TestTLuaEngine.SetUp;
begin
FLuaEngine := TLuaEngine.Create;
end;
procedure TestTLuaEngine.TearDown;
begin
FLuaEngine.Free;
FLuaEngine := nil;
end;
procedure TestTLuaEngine.TestLoadScript;
var
AScript: AnsiString;
begin
FLuaEngine.LoadScript(AScript);
FLuaEngine.Execute;
FLuaEngine.LoadScript('local x = 1+2+3;');
FLuaEngine.Execute;
ExpectedException := ELuaRuntimeException;
FLuaEngine.LoadScript('local x = pippo.makeBooom();');
FLuaEngine.Execute;
end;
procedure TestTLuaEngine.TestLoadScript1;
var
AStream: TStream;
begin
AStream := TFile.OpenRead('test_01.lua');
FLuaEngine.LoadScript(AStream, true);
FLuaEngine.Execute;
end;
procedure TestTLuaEngine.TestMyDirtyTests;
begin
FLuaEngine.LoadExternalLibraries(TLuaMyTest.Create);
FLuaEngine.LoadFromFile('test_mydirtytest.lua');
FLuaEngine.Execute;
end;
procedure TestTLuaEngine.TestPushTableFromCompoundObject;
var
father, Child: TPerson;
begin
father := TPerson.Create;
try
father.Child := TPerson.Create;
try
father.FirstName := 'Daniele';
father.LastName := 'Teti';
father.Age := 32;
father.Child.FirstName := 'Daniele Son';
father.Child.LastName := 'Teti';
father.Child.Age := 2;
father.Child.Child := nil;
FLuaEngine.DeclareTable('person', father);
FLuaEngine.LoadScript
('s = person.FirstName .. person.LastName .. tostring(person.Age) .. person.Child.FirstName .. person.Child.LastName .. person.Child.Age');
FLuaEngine.Execute;
CheckEquals('DanieleTeti32Daniele SonTeti2', FLuaEngine.GetGlobal('s').GetAsString);
finally
father.Child.Free;
end;
finally
father.Free;
end;
end;
procedure TestTLuaEngine.TestPushTableWithIntegerKeys;
begin
FLuaEngine.DeclareTable('mytable', [1, 2, 3, 4], ['daniele', 'teti', 'peter', 'parker']);
FLuaEngine.LoadScript('s = mytable[1]..mytable[2]..mytable[3]..mytable[4]');
FLuaEngine.Execute;
CheckEquals('danieletetipeterparker', FLuaEngine.GetGlobal('s').GetAsString)
end;
procedure TestTLuaEngine.TestPushTableWithStringKeys;
begin
FLuaEngine.DeclareTable('mytable', ['a', 'b', 'c', 'd'], ['daniele', 'teti', 'peter', 'parker']);
FLuaEngine.LoadScript(
's1 = mytable["a"] .. mytable["b"] .. mytable["c"] .. mytable["d"];' +
's2 = mytable.a .. mytable.b .. mytable.c .. mytable.d');
FLuaEngine.Execute;
CheckEquals('danieletetipeterparker', FLuaEngine.GetGlobal('s1').GetAsString);
CheckEquals('danieletetipeterparker', FLuaEngine.GetGlobal('s2').GetAsString)
end;
procedure TestTLuaEngine.TestPushTableWithTValueValues;
var
dict: TDictionary<TValue, TValue>;
begin
dict := TDictionary<TValue, TValue>.Create;
try
dict.AddOrSetValue('hello', 'world');
dict.AddOrSetValue(1234, 'onetwothree');
dict.AddOrSetValue('yes', true);
dict.AddOrSetValue('no', false);
FLuaEngine.DeclareTable('mytable', dict);
FLuaEngine.LoadScript
('s = mytable.hello .. mytable[1234] .. tostring(mytable.yes) .. tostring(mytable["no"])');
FLuaEngine.Execute;
CheckEquals('worldonetwothreetruefalse', FLuaEngine.GetGlobal('s').GetAsString)
finally
dict.Free;
end;
end;
procedure TestTLuaEngine.TestLoadFromFile;
begin
FLuaEngine.LoadFromFile('test_01.lua');
FLuaEngine.Execute;
end;
procedure TestTLuaEngine.TestDeclareGlobalNil;
begin
FLuaEngine.DeclareGlobalNil('_nil');
FLuaEngine.LoadScript('');
FLuaEngine.Execute;
CheckTrue(FLuaEngine.GetGlobal('_nil').IsNil);
end;
procedure TestTLuaEngine.TestDeclareGlobalNumber;
var
Value : ILuaValue;
_tot, _number1, _number2, _number3, _number4: Double;
begin
_number1 := 1;
_number2 := 1.1234;
_number3 := 1234.5678;
_number4 := 12345678;
FLuaEngine.DeclareGlobalNumber('_number1', _number1);
FLuaEngine.DeclareGlobalNumber('_number2', _number2);
FLuaEngine.DeclareGlobalNumber('_number3', _number3);
FLuaEngine.DeclareGlobalNumber('_number4', _number4);
FLuaEngine.LoadScript('_tot = _number1 + _number2 + _number3 + _number4;');
FLuaEngine.Execute;
Value := FLuaEngine.GetGlobal('_tot');
CheckTrue(Value.IsNumber);
CheckFalse(Value.IsInteger);
CheckFalse(Value.IsString);
CheckFalse(Value.IsNil);
CheckFalse(Value.IsBoolean);
CheckFalse(Value.IsLightUserData);
_tot := _number1 + _number2 + _number3 + _number4;
CheckTrue(abs(_tot - Value.GetAsNumber) < 0.0001);
ExpectedException := ELuaException;
Value.GetAsString;
end;
procedure TestTLuaEngine.TestDeclareGlobalInteger;
var
Value : ILuaValue;
_tot, _number1, _number2, _number3, _number4: Integer;
begin
_number1 := 1;
_number2 := 1234;
_number3 := 12345678;
_number4 := 12345678;
FLuaEngine.DeclareGlobalInteger('_number1', _number1);
FLuaEngine.DeclareGlobalInteger('_number2', _number2);
FLuaEngine.DeclareGlobalInteger('_number3', _number3);
FLuaEngine.DeclareGlobalInteger('_number4', _number4);
FLuaEngine.LoadScript('_tot = _number1 + _number2 + _number3 + _number4;');
FLuaEngine.Execute;
Value := FLuaEngine.GetGlobal('_tot');
CheckTrue(Value.IsNumber);
/// a sum of integers returns a NUMBER result type.. :-(
CheckFalse(Value.IsInteger);
CheckFalse(Value.IsString);
CheckFalse(Value.IsNil);
CheckFalse(Value.IsBoolean);
CheckFalse(Value.IsLightUserData);
_tot := _number1 + _number2 + _number3 + _number4;
CheckTrue(abs(_tot - Value.GetAsNumber) < 0.0001);
ExpectedException := ELuaException;
Value.GetAsString;
end;
procedure TestTLuaEngine.TestDeclareGlobalString;
var
Value : ILuaValue;
_tot, _string1, _string2, _string3, _string4: AnsiString;
begin
_string1 := '';
_string2 := 'hello';
_string3 := 'Lua';
_string4 := 'world <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>$%';
FLuaEngine.DeclareGlobalString('_string1', _string1);
FLuaEngine.DeclareGlobalString('_string2', _string2);
FLuaEngine.DeclareGlobalString('_string3', _string3);
FLuaEngine.DeclareGlobalString('_string4', _string4);
FLuaEngine.LoadScript('_tot = _string1 .. _string2 .. _string3 .. _string4;');
FLuaEngine.Execute;
Value := FLuaEngine.GetGlobal('_tot');
CheckFalse(Value.IsNumber);
CheckFalse(Value.IsInteger);
CheckTrue(Value.IsString);
CheckFalse(Value.IsNil);
CheckFalse(Value.IsBoolean);
CheckFalse(Value.IsLightUserData);
_tot := _string1 + _string2 + _string3 + _string4;
CheckEquals('helloLuaworld <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>$%', _tot);
ExpectedException := ELuaException;
Value.GetAsInteger;
end;
procedure TestTLuaEngine.TestDeclareGlobalUserData;
begin
// FLuaEngine.DeclareGlobalUserData('pippo', nil);
// FLuaEngine.LoadScript('');
// FLuaEngine.Execute;
end;
procedure TestTLuaEngine.TestExecuteFunction;
var
r: AnsiString;
begin
FLuaEngine.LoadScript('function myfunc(a,b,c) return a..b..c end');
FLuaEngine.Execute;
r := FLuaEngine.ExecuteFunction('myfunc', ['hello', 'Lua', 'world']).AsString;
CheckEquals('helloLuaworld', r);
FLuaEngine.Reset;
FLuaEngine.LoadFromFile('test_08.lua');
FLuaEngine.Execute;
r := FLuaEngine.ExecuteFunction('myfunc', ['hello', 'Lua', 'world']).AsString;
CheckEquals('helloLuaworld', r);
end;
procedure TestTLuaEngine.TestExposeDataSet;
var
ds: TClientDataSet;
_1: string;
_2: string;
begin
ds := TClientDataSet.Create(nil);
try
ds.LoadFromFile('samplecds.xml');
ds.Open;
FLuaEngine.LoadExternalLibraries(TLuaDataSetExposerLibraries.Create);
ExposeDataSet(FLuaEngine, ds, 'people');
FLuaEngine.LoadFromFile('test_02.lua');
FLuaEngine.Execute;
finally
ds.Free;
end;
_1 := TFile.ReadAllText('test_02_expected.txt');
_2 := TFile.ReadAllText('test_02.txt');
CheckEquals(_1, _2);
end;
procedure TestTLuaEngine.TestExposeDelphiObject;
var
person: TPerson;
begin
person := TPerson.Create;
try
FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create);
ExposeDelphiObject(FLuaEngine, person, 'person');
FLuaEngine.LoadFromFile('test_03.lua');
FLuaEngine.Execute;
CheckEquals('Teti', FLuaEngine.GetGlobal('last_name').GetAsString);
CheckEquals('Daniele', FLuaEngine.GetGlobal('first_name').GetAsString);
CheckEquals('Mr. Daniele Teti', FLuaEngine.GetGlobal('full_name').GetAsString);
CheckEquals(32, FLuaEngine.GetGlobal('age').GetAsInteger);
CheckEquals('Teti', person.LastName);
CheckEquals('Daniele', person.FirstName);
CheckEquals(32, person.Age);
finally
person.Free;
end;
end;
procedure TestTLuaEngine.TestExposeDelphiObjectNoDeps;
var
person: TPerson;
begin
person := TPerson.Create;
try
person.FirstName := 'Daniele';
person.LastName := 'Teti';
person.Age := 33;
FLuaEngine.DeclareGlobalDelphiObjectAsTable(person, 'person');
// FLuaEngine.ExecuteScript('r = person.FirstName .. person.LastName .. tostring(person.Age)');
// CheckEquals('DanieleTeti33', FLuaEngine.GetGlobal('r').GetAsString);
FLuaEngine.LoadScript('x = person:hello("parametro1", "parametro2")');
FLuaEngine.Execute;
// FLuaEngine.ExecuteScript('person:BecomeOlder(1)');
CheckEquals('DanieleTeti34', FLuaEngine.GetGlobal('x').GetAsString);
finally
person.Free;
end;
end;
procedure TestTLuaEngine.TestExposeVCLDelphiObject;
var
sl: TStringList;
begin
sl := TStringList.Create;
try
sl.Add('first');
FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create);
ExposeDelphiObject(FLuaEngine, sl, 'stringlist');
FLuaEngine.LoadFromFile('test_04.lua');
FLuaEngine.Execute;
CheckEquals(4, sl.Count);
finally
sl.Free;
end;
end;
procedure TestTLuaEngine.TestExposeVCLDelphiObjectSetProperty;
var
sl: TStringList;
begin
sl := TStringList.Create;
try
sl.Add('first');
sl.Add('two');
sl.Add('three');
FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create);
ExposeDelphiObject(FLuaEngine, sl, 'stringlist');
FLuaEngine.LoadFromFile('test_05.lua');
FLuaEngine.Execute;
CheckEquals(1, sl.Count);
CheckEquals('Daniele Teti', sl[0]);
finally
sl.Free;
end;
end;
procedure TestTLuaEngine.TestCreateDelphiObject;
begin
FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create);
FLuaEngine.LoadFromFile('test_06.lua');
FLuaEngine.Execute;
end;
procedure TestTLuaEngine.TestCreateDelphiObjectWithWringConstructor;
begin
FLuaEngine.LoadExternalLibraries(TLuaDelphiObjectExposerLibraries.Create);
FLuaEngine.LoadFromFile('test_07.lua');
ExpectedException := ELuaRuntimeException;
FLuaEngine.Execute;
end;
procedure TestTLuaEngine.TestDeclareGlobalBoolean;
var
Value : ILuaValue;
_tot, _boolean1, _boolean2, _boolean3, _boolean4: boolean;
begin
_boolean1 := true;
_boolean2 := false;
_boolean3 := true;
_boolean4 := false;
FLuaEngine.DeclareGlobalBoolean('_boolean1', _boolean1);
FLuaEngine.DeclareGlobalBoolean('_boolean2', _boolean2);
FLuaEngine.DeclareGlobalBoolean('_boolean3', _boolean3);
FLuaEngine.DeclareGlobalBoolean('_boolean4', _boolean4);
FLuaEngine.LoadScript('_tot = _boolean1 or _boolean2 and _boolean3 or _boolean4;');
FLuaEngine.Execute;
Value := FLuaEngine.GetGlobal('_tot');
CheckFalse(Value.IsNumber);
CheckFalse(Value.IsInteger);
CheckFalse(Value.IsString);
CheckFalse(Value.IsNil);
CheckTrue(Value.IsBoolean);
CheckFalse(Value.IsLightUserData);
_tot := _boolean1 or _boolean2 and _boolean3 or _boolean4;
CheckEquals(_tot, Value.GetAsBoolean);
ExpectedException := ELuaException;
Value.GetAsString;
end;
procedure TestTLuaEngine.TestDeclareGlobalFunction;
function SayHello(L: Plua_State): Integer; cdecl;
var
s: AnsiString;
begin
s := lua_tostring(L, - 1);
s := 'before ' + s + ' after';
lua_pop(L, 1);
lua_pushstring(L, PAnsiChar(s));
Result := 1;
end;
var
Value: ILuaValue;
begin
FLuaEngine.DeclareGlobalFunction('sayhello', @SayHello);
FLuaEngine.LoadScript('x = sayhello("hello world")');
FLuaEngine.Execute;
Value := FLuaEngine.GetGlobal('x');
CheckEquals('before hello world after', Value.GetAsString);
end;
procedure TestTLuaEngine.TestDeclareGlobalLightUserData;
var
Value: ILuaValue;
_ptr : Pointer;
Obj : TStringList;
Obj2 : TStringList;
function AddToTStringList(L: Plua_State): Integer; cdecl;
var
sl: TStringList;
s : AnsiString;
begin
s := lua_tostring(L, - 1);
lua_pop(L, 1);
sl := TStringList(lua_topointer(L, - 1));
lua_pop(L, 1);
sl.Add(s);
Result := 0;
end;
begin
_ptr := nil;
FLuaEngine.DeclareGlobalLightUserData('_ptr', _ptr);
FLuaEngine.LoadScript('x = _ptr');
FLuaEngine.Execute;
Value := FLuaEngine.GetGlobal('x');
CheckTrue(Value.IsLightUserData);
CheckTrue(Value.GetAsLightUserData = nil);
// Now try to pass a tstringlist
Obj := TStringList.Create;
try
Obj.Add('Hello World');
_ptr := Pointer(Obj);
FLuaEngine.DeclareGlobalLightUserData('_ptr1', _ptr);
FLuaEngine.DeclareGlobalFunction('additem', @AddToTStringList);
FLuaEngine.LoadScript('x = _ptr1; additem(x,"added from Lua")');
FLuaEngine.Execute;
Value := FLuaEngine.GetGlobal('x');
CheckFalse(Value.IsNumber);
CheckFalse(Value.IsInteger);
CheckFalse(Value.IsString);
CheckFalse(Value.IsNil);
CheckFalse(Value.IsBoolean);
CheckTrue(Value.IsLightUserData);
CheckNotNull(Value.GetAsLightUserData);
_ptr := Value.GetAsLightUserData;
Obj2 := TStringList(_ptr);
CheckEquals(2, Obj2.Count);
CheckEquals('Hello World', Obj2[0]);
CheckEquals('added from Lua', Obj2[1]);
finally
Obj.Free;
end;
ExpectedException := ELuaException;
Value.GetAsString;
end;
procedure TestTLuaEngine.TestGetGlobal;
var
ReturnValue: ILuaValue;
AName : AnsiString;
begin
// TODO: Setup method call parameters
ReturnValue := FLuaEngine.GetGlobal(AName);
// TODO: Validate method results
end;
{ TPerson }
initialization
// Register any test cases with the test runner
RegisterTest(TestTLuaEngine.Suite);
end.