fpc/packages/fcl-base/tests/utcchainstream.pp
2022-11-23 12:55:14 +01:00

366 lines
8.4 KiB
ObjectPascal

unit utcchainstream;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, fpcunit, testregistry, chainstream;
Type
{ TTestChainStream }
TTestChainStream = Class (TTestCase)
private
FStreams : Array of TStream;
FStream: TChainedStream;
procedure ClearStreams;
Public
Function CreateStream(aOffset,aCount : Word) : TStream;
Procedure CreateChainedStream(Sizes : Array of Word; aOffset : Word = 0);
Procedure Setup; override;
Procedure TearDown; override;
Property Stream : TChainedStream Read FStream;
Published
Procedure TestEmpty;
Procedure TestCreateStream;
Procedure TestCreateStreams;
Procedure TestCreateStreams2;
Procedure TestOneStreamRead;
Procedure TestTwoStreamsRead;
Procedure TestTwoStreamsReadCrossBuffer;
Procedure TestTwoStreamsWrite;
Procedure TestTwoStreamsWriteCrossBuffer;
Procedure TestStreamsSeekFromEnd1;
Procedure TestStreamsSeekFromEnd2;
Procedure TestStreamsSeekFromBeginning1;
Procedure TestStreamsSeekFromBeginning2;
Procedure TestStreamsSeekFromCurrent1;
Procedure TestStreamsSeekFromCurrent2;
end;
implementation
{ TTestChainStream }
function TTestChainStream.CreateStream(aOffset, aCount: Word): TStream;
Var
I : integer;
begin
Result:=TMemoryStream.Create;
For I:=0 to aCount-1 do
begin
Result.WriteBuffer(aOffset,SizeOf(Word));
Inc(aOffset);
end;
Result.Position:=0;
end;
procedure TTestChainStream.CreateChainedStream(Sizes: array of Word; aOffset : Word = 0);
Var
I : integer;
aSize : Word;
begin
AssertTrue('Must have at least one stream size',Length(Sizes)>0);
ClearStreams;
SetLength(FStreams,Length(Sizes));
For I:=0 to Length(FStreams)-1 do
begin
aSize:=Sizes[i];
FStreams[i]:=CreateStream(aOffset,aSize);
Inc(aOffset,aSize);
end;
FStream:=TChainedStream.Create(FStreams,False);
end;
procedure TTestChainStream.Setup;
begin
inherited Setup;
end;
procedure TTestChainStream.ClearStreams;
var
I : Integer;
begin
if Assigned(FStream) then
begin
if FStream.OwnsStreams then
FStreams:=[];
FStream.Free;
end;
For I:=0 to Length(FStreams)-1 do
FStreams[i].Free;
end;
procedure TTestChainStream.TearDown;
begin
ClearStreams;
inherited TearDown;
end;
procedure TTestChainStream.TestEmpty;
begin
AssertNull('No stream',FStream);
AssertEquals('No streams',0,Length(FStreams));
end;
procedure TTestChainStream.TestCreateStream;
var
S : TStream;
I,W : Word;
begin
S:=CreateStream(10,3);
try
AssertEquals('Stream position',0,S.Position);
AssertEquals('Stream size',6,S.Size);
For I:=10 to 12 do
begin
S.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct byte read',I,W);
end;
finally
S.Free;
end;
end;
procedure TTestChainStream.TestCreateStreams;
begin
CreateChainedStream([10]);
AssertEquals('Correct stream count',1,Length(FStreams));
AssertEquals('Count',1,Stream.StreamCount);
AssertSame('Stream',FStreams[0],Stream.Streams[0]);
AssertEquals('Total size',20,Stream.Size);
end;
procedure TTestChainStream.TestCreateStreams2;
begin
CreateChainedStream([10,10]);
AssertEquals('Correct stream count',2,Length(FStreams));
AssertEquals('Count',2,Stream.StreamCount);
AssertSame('Stream 0',FStreams[0],Stream.Streams[0]);
AssertSame('Stream 1',FStreams[1],Stream.Streams[1]);
AssertEquals('Total size',40,Stream.Size);
end;
procedure TTestChainStream.TestOneStreamRead;
Var
I : Integer;
W : Word;
begin
CreateChainedStream([10]);
For I:=0 to 9 do
begin
Stream.ReadBuffer(W,SizeOf(W));
AssertEquals('Correct bytes read',I,W)
end;
end;
procedure TTestChainStream.TestTwoStreamsRead;
Var
I : Integer;
W : Word;
begin
CreateChainedStream([10,10]);
For I:=0 to 19 do
begin
Stream.ReadBuffer(W,SizeOf(W));
AssertEquals('Correct bytes read',I,W)
end;
end;
procedure TTestChainStream.TestTwoStreamsReadCrossBuffer;
Var
I : Integer;
W : Array of Word;
begin
SetLength(W,20);
CreateChainedStream([10,10]);
Stream.ReadBuffer(W[0],Length(W)*SizeOf(Word));
For I:=0 to 19 do
begin
AssertEquals('Correct bytes read',I,W[i])
end;
end;
procedure TTestChainStream.TestTwoStreamsWrite;
Var
I : Integer;
W : Word;
begin
CreateChainedStream([10,10]);
For I:=100 to 119 do
begin
W:=I;
Stream.WriteBuffer(W,SizeOf(W));
end;
Stream.Position:=0;
For I:=100 to 119 do
begin
Stream.ReadBuffer(W,SizeOf(W));
AssertEquals('Correct bytes read',I,W)
end;
end;
procedure TTestChainStream.TestTwoStreamsWriteCrossBuffer;
Var
I : Integer;
W : Array of Word;
WW : Word;
begin
SetLength(W,20);
For I:=0 to 19 do
W[i]:=I;
CreateChainedStream([10,10]);
Stream.WriteBuffer(W[0],Length(W)*SizeOf(Word));
FStreams[0].Position:=0;
For I:=0 to 9 do
begin
FStreams[0].ReadBuffer(WW,SizeOf(WW));
AssertEquals('Correct bytes read',I,WW)
end;
FStreams[1].Position:=0;
For I:=10 to 19 do
begin
FStreams[1].ReadBuffer(WW,SizeOf(WW));
AssertEquals('Correct bytes read',I,WW)
end;
end;
procedure TTestChainStream.TestStreamsSeekFromEnd1;
Var
W : Word;
begin
CreateChainedStream([10,10]);
AssertEquals('Seek',38,Stream.Seek(-2,soEnd));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read',19,W);
AssertEquals('Seek 2',20,Stream.Seek(-20,soEnd));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read 2',10,W);
AssertEquals('Seek 3',18,Stream.Seek(-22,soEnd));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read 2',9,W);
end;
procedure TTestChainStream.TestStreamsSeekFromEnd2;
Var
W : Word;
begin
CreateChainedStream([10,10,10]);
AssertEquals('Seek',0,Stream.Seek(-60,soEnd));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read ',0,W);
AssertEquals('Seek',30,Stream.Seek(-30,soEnd));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read ',15,W);
end;
procedure TTestChainStream.TestStreamsSeekFromBeginning1;
Var
W : Word;
begin
CreateChainedStream([10,10]);
AssertEquals('Seek',38,Stream.Seek(38,soBeginning));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read',19,W);
AssertEquals('Seek 2',20,Stream.Seek(20,soBeginning));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read 2',10,W);
AssertEquals('Seek 3',18,Stream.Seek(18,soBeginning));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read 2',9,W);
end;
procedure TTestChainStream.TestStreamsSeekFromBeginning2;
Var
W : Word;
begin
CreateChainedStream([10,10,10]);
AssertEquals('Seek',0,Stream.Seek(0,soBeginning));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read ',0,W);
AssertEquals('Seek',30,Stream.Seek(30,soBeginning));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read ',15,W);
AssertEquals('Seek',50,Stream.Seek(50,soBeginning));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read ',25,W);
end;
procedure TTestChainStream.TestStreamsSeekFromCurrent1;
Var
W : Word;
begin
CreateChainedStream([10,10]);
AssertEquals('Seek',4,Stream.Seek(4,soCurrent));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read 1',2,W);
AssertEquals('Position after read 1',6,Stream.Position);
AssertEquals('Seek 2',26,Stream.Seek(20,soCurrent));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read 2',13,W);
AssertEquals('Position after read 2',28,Stream.Position);
AssertEquals('Seek 3',32,Stream.Seek(4,soCurrent));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read 3',16,W);
AssertEquals('Position after read 2',34,Stream.Position);
end;
procedure TTestChainStream.TestStreamsSeekFromCurrent2;
Var
W : Word;
I : Integer;
begin
CreateChainedStream([10,10]);
For I:=1 to 15 do
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Position after reading data',30,Stream.Position);
AssertEquals('Seek',26,Stream.Seek(-4,soCurrent));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read 1',13,W);
AssertEquals('Position after read 1',28,Stream.Position);
AssertEquals('Seek 2',8,Stream.Seek(-20,soCurrent));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read 2',4,W);
AssertEquals('Position after read 2',10,Stream.Position);
AssertEquals('Seek 3',6,Stream.Seek(-4,soCurrent));
Stream.ReadBuffer(W,SizeOf(Word));
AssertEquals('Correct read 3',3,W);
AssertEquals('Position after read 2',8,Stream.Position);
end;
initialization
RegisterTest(TTestChainStream);
end.