Repository URL to install this package:
|
Version:
3.0.0 ▾
|
{$mode objfpc}
{$h+}
unit tcstreaming;
interface
Uses
SysUtils,Classes, fpcunit, testutils, testregistry;
Type
{ TTestStreaming }
TTestStreaming = Class(TTestCase)
Private
FStream : TMemoryStream;
Function ReadByte : byte;
Function ReadWord : Word;
Function ReadInteger : LongInt;
Function ReadInt64 : Int64;
function ReadBareStr: string;
function ReadString(V : TValueType): string;
function ReadWideString(V : TValueType): WideString;
Procedure Fail(FMt : String; Args : Array of const); overload;
Public
Procedure Setup; override;
Procedure TearDown; override;
Procedure SaveToStream(C : TComponent);
Function ReadValue : TValueType;
Procedure ExpectValue(AValue : TValueType);
Procedure ExpectFlags(Flags : TFilerFlags; APosition : Integer);
Procedure ExpectInteger(AValue : Integer);
Procedure ExpectByte(AValue : Byte);
Procedure ExpectInt64(AValue : Int64);
Procedure ExpectBareString(AValue : String);
Procedure ExpectString(AValue : String);
Procedure ExpectSingle(AValue : Single);
Procedure ExpectExtended(AValue : Extended);
Procedure ExpectCurrency(AValue : Currency);
Procedure ExpectIdent(AValue : String);
Procedure ExpectDate(AValue : TDateTime);
Procedure ExpectWideString(AValue : WideString);
Procedure ExpectEndofList;
Procedure ExpectSignature;
Procedure ExpectEndOfStream;
end;
implementation
uses typinfo;
Function ValName(V : TValueType) : String;
begin
Result:=GetEnumName(TypeInfo(TValueType),Ord(v));
end;
{ TTestStreaming }
procedure TTestStreaming.ExpectByte(AValue: Byte);
Var
B : Byte;
begin
B:=ReadByte;
If (B<>AValue) then
Fail('Expected byte %d, got %d',[AValue,B]);
end;
procedure TTestStreaming.ExpectCurrency(AValue: Currency);
Var
C : Currency;
begin
ExpectValue(vaCurrency);
FStream.Read(C,Sizeof(C));
If (C<>AValue) then
Fail('Expected currency %f, got %f',[AValue,C]);
end;
procedure TTestStreaming.ExpectDate(AValue: TDateTime);
Var
C : TDateTime;
begin
ExpectValue(vaDate);
FStream.Read(C,Sizeof(C));
If (C<>AValue) then
Fail('Expected datetime %f, got %f',[AValue,C]);
end;
procedure TTestStreaming.ExpectEndofList;
begin
ExpectValue(vaNull);
end;
procedure TTestStreaming.ExpectExtended(AValue: Extended);
Var
E : Extended;
begin
ExpectValue(vaExtended);
FStream.Read(E,Sizeof(E));
If Abs(E-AValue)>0.01 then
Fail('Expected extended %f, got %f',[AValue,E]);
end;
procedure TTestStreaming.ExpectFlags(Flags: TFilerFlags;
APosition: Integer);
var
Prefix: Byte;
F : TFilerFlags;
B : Byte;
I : Integer;
begin
F := [];
I:=0;
B:=ReadByte;
if B and $F0 = $F0 then
begin
Integer(F) := B and $0F;
if ffChildPos in Flags then
I:=ReadInteger;
end
else
FStream.Position:=FStream.Position-1;
If (FLags<>F) then
Fail('Wrong Flags, expected %d, got %d',[Integer(Flags),B]);
If I<>APosition then
Fail('Wrong position, expected %d, got %d',[APosition,I]);
end;
procedure TTestStreaming.ExpectIdent(AValue: String);
var
L : Byte;
V : TValueType;
S : String;
begin
V:=ReadValue;
case V of
vaIdent:
begin
L:=ReadByte;
SetLength(S,L);
FStream.Read(S[1], L);
end;
vaFalse:
S := 'False';
vaTrue:
S := 'True';
vaNil:
S := 'nil';
vaNull:
S := 'Null';
else
Fail('Expected identifier property type, got %s',[valName(V)]);
end;
If (S<>AValue) then
Fail('Wrong identifier %s, expected %s',[S,AValue]);
end;
procedure TTestStreaming.ExpectInt64(AValue: Int64);
Var
V : TValueType;
I : Int64;
begin
V:=ReadValue;
Case V of
vaInt8 : I:=ReadByte;
vaInt16 : I:=ReadWord;
vaInt32 : I:=ReadInteger;
vaInt64 : I:=ReadInt64;
else
Fail('Expected integer property type, got %s',[valName(V)]);
end;
If (AValue<>I) then
Fail('Expected integer %d, but got %d',[AValue,I]);
end;
procedure TTestStreaming.ExpectInteger(AValue: Integer);
Var
V : TValueType;
I : Integer;
begin
V:=ReadValue;
Case V of
vaInt8 : I:=ReadByte;
vaInt16 : I:=ReadWord;
vaInt32 : I:=ReadInteger;
else
Fail('Expected integer property type, got %s',[valName(V)]);
end;
If (AValue<>I) then
Fail('Expected integer %d, but got %d',[AValue,I]);
end;
procedure TTestStreaming.ExpectSignature;
const
Sig : array[1..4] of Char = 'TPF0';
var
E,L : Longint;
begin
L:=ReadInteger;
E:=Longint(Sig);
if L<>E then
Fail('Invalid signature %d, expected %d',[L,E]);
end;
procedure TTestStreaming.ExpectSingle(AValue: Single);
Var
S : Single;
begin
ExpectValue(vaSingle);
FStream.Read(S,SizeOf(Single));
If Abs(AValue-S)>0.0001 then
Fail('Expected single %f, but got %s',[AValue,S]);
end;
function TTestStreaming.ReadString(V : TValueType): string;
var
L: Integer;
B : Byte;
begin
If V in [vaWString, vaUTF8String] then
Result := ReadWideString(V)
else
begin
L := 0;
case V of
vaString:
begin
FStream.Read(B, SizeOf(B));
L:=B;
end;
vaLString:
FStream.Read(L, SizeOf(Integer));
else
Fail('Wrong type %s, expected string type.',[ValName(V)]);
end;
SetLength(Result, L);
If (L>0) then
FStream.Read(PByte(Result)^, L);
end;
end;
function TTestStreaming.ReadWideString(V : TValueType): WideString;
var
L: Integer;
Temp: String;
begin
if V in [vaString, vaLString] then
Result := ReadString(V)
else
begin
L := 0;
case V of
vaWString:
begin
FStream.Read(L, SizeOf(Integer));
SetLength(Result, L);
FStream.Read(Pointer(Result)^, L * 2);
end;
vaUTF8String:
begin
FStream.Read(L, SizeOf(Integer));
SetLength(Temp, L);
FStream.Read(Pointer(Temp)^, L);
Result:=Temp
end;
else
Fail('Wrong type %s, expected widestring type.',[ValName(V)]);
end;
end;
end;
procedure TTestStreaming.ExpectString(AValue: String);
Var
V : TValueType;
S : String;
begin
V:=ReadValue;
If v in [vaString,vaLstring,vaWString,vaUTF8String] then
S:=ReadString(V)
else
Fail('Expected string type, but got : %s',[ValName(V)]);
If (S<>AValue) then
Fail('Expected string "%s", but got "%s"',[AVAlue,S]);
end;
procedure TTestStreaming.ExpectValue(AValue: TValueType);
Var
V : TValueType;
begin
V:=ReadValue;
If (V<>AValue) then
Fail('Expecting value %s, but read %s',[ValName(AValue),ValName(V)]);
end;
procedure TTestStreaming.ExpectWideString(AValue: WideString);
Var
W : WideString;
V : TValueType;
begin
V:=ReadValue;
If v in [vaString,vaLstring,vaWString,vaUTF8String] then
W:=ReadWideString(V)
else
Fail('Expected string type, but got : %s',[ValName(V)]);
If (W<>AValue) then
Fail('Expected string "%s", but got "%s"',[AVAlue,W]);
end;
procedure TTestStreaming.Fail(Fmt: String; Args: array of const);
begin
Fail(Format(Fmt,Args));
end;
function TTestStreaming.ReadValue: TValueType;
{$IFDEF FPC}
var b : byte;
{$ENDIF}
begin
{$IFDEF FPC}
FStream.Read(b,1);
result := TValueType(b);
{$ELSE}
FStream.Read(Result,SizeOf(Result));
{$ENDIF}
end;
procedure TTestStreaming.Setup;
begin
FStream:=TMemoryStream.Create;
end;
procedure TTestStreaming.SaveToStream(C: TComponent);
var
s: TStream;
begin
C.Name:='Test'+C.ClassName;
FStream.Clear;
FStream.WriteComponent(C);
FStream.Position:=0;
// for debugging purposes, you can write a component to file too
// set the class name of the component you want to write to disk in the next line
if (C.ClassName='TStreamedOwnedComponentsX') then begin
s := TFileStream.Create(C.ClassName+'.txt', fmCreate, fmShareDenyNone );
s.WriteComponent(C);
s.Free;
end;
end;
procedure TTestStreaming.TearDown;
begin
FreeAndNil(FStream);
end;
function TTestStreaming.ReadByte: byte;
begin
FStream.Read(Result,SizeOf(Result));
end;
function TTestStreaming.ReadInt64: Int64;
begin
FStream.Read(Result,SizeOf(Result));
end;
function TTestStreaming.ReadInteger: LongInt;
begin
FStream.Read(Result,SizeOf(Result));
end;
function TTestStreaming.ReadWord: Word;
begin
FStream.Read(Result,SizeOf(Result));
end;
function TTestStreaming.ReadBareStr: string;
var
L: Byte;
begin
L:=ReadByte;
SetLength(Result,L);
Fstream.Read(Result[1], L);
end;
procedure TTestStreaming.ExpectBareString(AValue: String);
Var
S : String;
begin
S:=ReadBareStr;
If (S<>AValue) then
Fail('Expected bare string %s, got :%s',[AValue,S]);
end;
procedure TTestStreaming.ExpectEndOfStream;
begin
If (FStream.Position<>FStream.Size) then
Fail('Expected at end of stream, current position=%d, size=%d',
[FStream.Position,FStream.Size]);
end;
end.