xtool/contrib/mORMot/SQLite3/Samples/29 - SmartMobileStudio Client/SmartTests.pas

272 lines
8.0 KiB
ObjectPascal

unit SmartTests;
interface
uses
SmartCL.System,
System.Types,
ECMA.Date,
System.Date,
SynCrossPlatformSpecific,
SynCrossPlatformREST,
SynCrossPlatformCrypto;
procedure TestSMS;
procedure ORMTest(client: TSQLRestClientURI);
procedure SOATest(client: TSQLRestClientURI; onSuccess, onError: TSQLRestEvent);
implementation
uses
mORMotClient; // unit generated by the server!
const
MSecsPerDay = 86400000;
OneSecDateTime = 1/SecsPerDay;
procedure TestsIso8601DateTime;
procedure Test(D: TDateTime);
var s: string;
procedure One(D: TDateTime);
var E: TDateTime;
V: TTimeLog;
J: JDate;
begin
J := new JDate;
J.AsDateTime := D;
E := J.AsDateTime;
assert(Abs(D-E)<OneSecDateTime);
s := DateTimeToIso8601(D);
E := Iso8601ToDateTime(s);
assert(Abs(D-E)<OneSecDateTime);
V := DateTimeToTTimeLog(D);
E := TTimeLogToDateTime(V);
assert(Abs(D-E)<OneSecDateTime);
assert(UrlDecode(UrlEncode(s))=s);
end;
begin
One(D);
assert(length(s)=19);
One(Trunc(D));
assert(length(s)=10);
One(Frac(D));
assert(length(s)=9);
end;
var D: TDateTime;
i: integer;
s,x: string;
T: TTimeLog;
begin
s := '2014-06-28T11:50:22';
D := Iso8601ToDateTime(s);
assert(DateTimeToIso8601(D)=s);
assert(Abs(D-41818.40997685185)<OneSecDateTime);
x := TTimeLogToIso8601(135181810838);
assert(x=s);
T := DateTimeToTTimeLog(D);
assert(T=135181810838);
D := Now/20+Random*20; // some starting random date/time
for i := 1 to 2000 do begin
Test(D);
D := D+Random*57; // go further a little bit: change date/time
end;
end;
procedure TestSMS;
var doc: TJSONVariantData;
begin
assert(crc32ascii(0,'abcdefghijklmnop')=$943AC093);
assert(SHA256('abc')='ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad');
assert(VariantType(123)=jvUndefined);
assert(VariantType(null)=jvUndefined);
assert(VariantType(TVariant.CreateObject)=jvObject);
assert(VariantType(new JObject)=jvObject);
assert(VariantType(TVariant.CreateArray)=jvArray);
doc := TJSONVariantData.Create('{"a":1,"b":"B"}');
assert(doc.Kind=jvObject);
assert(doc.Count=2);
assert(doc.Names[0]='a');
assert(doc.Names[1]='b');
assert(doc.Values[0]=1);
assert(doc.Values[1]='B');
doc := TJSONVariantData.Create('["a",2]');
assert(doc.Kind=jvArray);
assert(doc.Count=2);
assert(doc.Names.Count=0);
assert(doc.Values[0]='a');
assert(doc.Values[1]=2);
TestsIso8601DateTime;
end;
procedure ORMTest(client: TSQLRestClientURI);
var people: TSQLRecordPeople;
Call: TSQLRestURIParams;
res: TIntegerDynArray;
i,id: integer;
begin // all this is run in synchronous mode -> only 200 records in the set
client.CallBackGet('DropTable',[],Call,TSQLRecordPeople);
assert(client.InternalState>0);
assert(Call.OutStatus=HTTP_SUCCESS);
client.BatchStart(TSQLRecordPeople);
people := TSQLRecordPeople.Create;
assert(people.InternalState=0);
for i := 1 to 200 do begin
people.FirstName := 'First'+IntToStr(i);
people.LastName := 'Last'+IntToStr(i);
people.YearOfBirth := i+1800;
people.YearOfDeath := i+1825;
assert(client.BatchAdd(people,true)=i-1);
assert(people.InternalState=0);
end;
assert(client.BatchSend(res)=HTTP_SUCCESS);
assert(length(res)=200);
for i := 1 to 200 do
assert(res[i-1]=i);
people := TSQLRecordPeople.CreateAndFillPrepare(client,'','',[]);
assert(people.InternalState=0);
id := 0;
while people.FillOne do begin
assert(people.InternalState=client.InternalState);
inc(id);
assert(people.ID=id);
assert(people.FirstName='First'+IntToStr(id));
assert(people.LastName='Last'+IntToStr(id));
assert(people.YearOfBirth=id+1800);
assert(people.YearOfDeath=id+1825);
end;
assert(id=200);
people.Free; // release all memory used by the request
people := TSQLRecordPeople.CreateAndFillPrepare(client,
'YearOFBIRTH,Yearofdeath,id','',[]);
assert(people.InternalState=0);
id := 0;
while people.FillOne do begin
assert(people.InternalState=client.InternalState);
inc(id);
assert(people.ID=id);
assert(people.FirstName='');
assert(people.LastName='');
assert(people.YearOfBirth=id+1800);
assert(people.YearOfDeath=id+1825);
end;
assert(id=200);
people.Free; // release all memory used by the request
people := TSQLRecordPeople.CreateAndFillPrepare(client,'',
'yearofbirth=?',[1900]);
id := 0;
while people.FillOne do begin
assert(people.InternalState=client.InternalState);
inc(id);
assert(people.ID=100);
assert(people.FirstName='First100');
assert(people.LastName='Last100');
assert(people.YearOfBirth=1900);
assert(people.YearOfDeath=1925);
end;
assert(id=1);
for i := 1 to 200 do
if i and 15=0 then
client.Delete(TSQLRecordPeople,i) else
if i mod 82=0 then begin
people := TSQLRecordPeople.Create;
id := i+1;
people.ID := i;
people.FirstName := 'neversent';
people.LastName := 'neitherthisone';
people.YearOfBirth := id+1800;
people.YearOfDeath := id+1825;
assert(people.InternalState=0);
assert(client.Update(people,'YEarOFBIRTH,YEarOfDeath'));
assert(people.InternalState=client.InternalState);
end;
people := new TSQLRecordPeople;
assert(people.InternalState=0);
for i := 1 to 200 do begin
var read = client.Retrieve(i,people);
if i and 15=0 then
assert(not read) else begin
assert(read);
assert(people.InternalState=client.InternalState);
if i mod 82=0 then
id := i+1 else
id := i;
assert(people.ID=i);
assert(people.FirstName='First'+IntToStr(i));
assert(people.LastName='Last'+IntToStr(i));
assert(people.YearOfBirth=id+1800);
assert(people.YearOfDeath=id+1825);
end;
end;
people.Free;
end;
procedure SOATest(client: TSQLRestClientURI; onSuccess, onError: TSQLRestEvent);
var Calc: TServiceCalculator;
i: integer;
const SEX_TEXT: array[0..1] of string = ('Miss','Mister');
ITERATIONS = 50;
begin
Calc := TServiceCalculator.Create(client); // no need to free instance on SMS
assert(Calc.InstanceImplementation=sicShared);
assert(Calc.ServiceName='Calculator');
// first test synchronous / blocking mode
for i := 1 to ITERATIONS do
assert(calc._Add(i,i+1)=i*2+1);
for i := 1 to ITERATIONS do begin
var sex := TPeopleSexe(i and 1);
var name := 'Smith';
calc._ToText(i,'$',sex,name);
assert(sex=sFemale);
assert(name=format('$ %d for %s Smith',[i,SEX_TEXT[i and 1]]));
end;
var j: integer;
var rec: TTestCustomJSONArraySimpleArray;
for i := 1 to ITERATIONS do begin
var name := calc._RecordToText(rec);
if i=1 then
assert(name='{"F":"","G":[],"H":{"H1":0,"H2":"","H3":{"H3a":false,"H3b":null}},"I":"","J":[]}');
assert(length(Rec.F)=i);
for j := 1 to length(Rec.F) do
assert(Rec.F[j]='!');
assert(length(Rec.G)=i);
for j := 0 to high(Rec.G) do
assert(Rec.G[j]=IntToStr(j+1));
assert(Rec.H.H1=i);
assert(length(Rec.J)=i-1);
for j := 0 to high(Rec.J) do begin
assert(Rec.J[j].J1=j);
assert(Rec.J[j].J2<>'');
assert(Rec.J[j].J3=TRecordEnum(j mod (ord(high(TRecordEnum))+1)));
end;
end;
// code below is asynchronous, so more difficult to follow than synchronous !
i := 1; // need two Calc*Asynch() inlined lambdas to access var i
procedure CalcToTextAsynch(sexe: TPeopleSexe; name: string);
begin
assert(sexe=sFemale);
assert(name=format('$ %d for %s Smith',[i,SEX_TEXT[i and 1]]));
inc(i);
sexe := TPeopleSexe(i and 1);
name := 'Smith';
if i<=ITERATIONS then // recursive for i := 1 to ITERATIONS
Calc.ToText(i,'$',sexe,name,CalcToTextAsynch,onError) else
onSuccess(client);
end;
procedure CalcAddAsynch(res: integer);
begin
assert(res=i*2+1);
inc(i);
if i<=ITERATIONS then // recursive for i := 1 to ITERATIONS
Calc.Add(i,i+1,CalcAddAsynch,onError) else begin
i := 1;
Calc.ToText(i,'$',TPeopleSexe(i and 1),'Smith',CalcToTextAsynch,onError);
end;
end;
Calc.Add(i,i+1,CalcAddAsynch,onError);
end;
end.