Files
fpc-msgbase/tests/test_roundtrip.pas
Ken Johnson a541085a4b 0.7.0: extract TFTNAddress into leaf mb.address unit
Ask 1 from fpc-binkp consumer thread: non-storage libraries
(fpc-ftn-transport, fpc-binkp, future fpc-comet-proto / fpc-emsi,
SQL-backed messaging like Fastway) only need TFTNAddress, not the
full 1041-line mb.types.  Extract to src/mb.address.pas (~90 lines,
only SysUtils) so they can cp a single file into their project.

mb.types continues to uses mb.address so existing callers see the
type transitively -- BUT FPC does not propagate record-field access
through re-export, so consumers that touch TFTNAddress.Zone/Net/
Node/Point directly must add mb.address to their own uses clause.
All 7 in-tree .uni adapters, 2 examples, 5 test harnesses updated.

No behavioural change.  Full suite passes, multi-target build
green (x86_64-linux, i386-{linux,freebsd,win32,os2,go32v2}).
2026-04-21 13:22:53 -07:00

135 lines
4.1 KiB
ObjectPascal

{
test_roundtrip.pas - write N messages through the unified API,
close, reopen, read them back and verify every field.
Runs against a scratch dir under /tmp so sample data stays
untouched. Covers Hudson, JAM, Squish, *.MSG, and GoldBase.
}
program test_roundtrip;
{$mode objfpc}{$H+}
uses
SysUtils,
testutil,
mb.address, mb.types, mb.events, mb.api,
mb.fmt.hudson, mb.fmt.hudson.uni,
mb.fmt.jam, mb.fmt.jam.uni,
mb.fmt.squish, mb.fmt.squish.uni,
mb.fmt.msg, mb.fmt.msg.uni,
mb.fmt.goldbase, mb.fmt.goldbase.uni;
const
SCRATCH_ROOT = '/tmp/ma_roundtrip';
procedure CleanDir(const APath: string);
var
sr: TSearchRec;
begin
if not DirectoryExists(APath) then exit;
if FindFirst(APath + '/*', faAnyFile, sr) = 0 then
try
repeat
if (sr.Attr and faDirectory) = 0 then
DeleteFile(APath + '/' + sr.Name);
until FindNext(sr) <> 0;
finally
FindClose(sr);
end;
end;
function MakeMsg(N: longint): TUniMessage;
begin
Result.Attributes.Clear;
Result.Attributes.SetValue('from', 'Sender' + IntToStr(N));
Result.Attributes.SetValue('to', 'Dest' + IntToStr(N));
Result.Attributes.SetValue('subject', 'Subject ' + IntToStr(N));
Result.Attributes.SetDate('date.written',
EncodeDate(2026, 4, 1) + EncodeTime(12, N mod 60, 0, 0));
Result.Attributes.SetBool('attr.local', true);
Result.Attributes.SetBool('attr.echo', true);
Result.Attributes.SetAddr('addr.orig', MakeFTNAddress(1, 100, 200, 0));
Result.Attributes.SetAddr('addr.dest', MakeFTNAddress(1, 100, 300, 0));
Result.Attributes.SetValue('area', 'TEST');
Result.Body := 'Body of message ' + IntToStr(N) + #13;
end;
procedure RoundTrip(AFormat: TMsgBaseFormat; const APath: string;
const ATestName: string; N: longint);
var
base: TMessageBase;
i: longint;
wmsg: TUniMessage;
rmsg: TUniMessage;
preCount: longint;
begin
TestBegin(ATestName);
ForceDirectories(ExtractFilePath(APath));
CleanDir(ExtractFilePath(APath));
{ Create + write phase }
base := MessageBaseOpen(AFormat, APath, momCreate);
try
AssertTrue('Open (write)', base.Open);
preCount := base.MessageCount;
for i := 1 to N do begin
wmsg := MakeMsg(i);
AssertTrue('WriteMessage ' + IntToStr(i), base.WriteMessage(wmsg));
end;
AssertEquals('Count after writes', preCount + N, base.MessageCount);
finally
base.Close;
base.Free;
end;
{ Reopen + read phase }
base := MessageBaseOpen(AFormat, APath, momReadOnly);
try
AssertTrue('Open (read)', base.Open);
AssertEquals('Count after reopen', preCount + N, base.MessageCount);
for i := 1 to N do begin
AssertTrue('ReadMessage ' + IntToStr(i),
base.ReadMessage(preCount + i - 1, rmsg));
AssertEquals('WhoFrom[' + IntToStr(i) + ']',
'Sender' + IntToStr(i), rmsg.Attributes.Get('from'));
AssertEquals('WhoTo[' + IntToStr(i) + ']',
'Dest' + IntToStr(i), rmsg.Attributes.Get('to'));
AssertEquals('Subject[' + IntToStr(i) + ']',
'Subject ' + IntToStr(i), rmsg.Attributes.Get('subject'));
AssertTrue('Body contains msg body[' + IntToStr(i) + ']',
Pos('Body of message ' + IntToStr(i), rmsg.Body) > 0);
end;
finally
base.Close;
base.Free;
end;
TestOK;
end;
begin
WriteLn('fpc-msgbase: round-trip tests');
WriteLn;
ForceDirectories(SCRATCH_ROOT);
ForceDirectories(SCRATCH_ROOT + '/hudson');
RoundTrip(mbfHudson, SCRATCH_ROOT + '/hudson/', 'Hudson round-trip', 5);
ForceDirectories(SCRATCH_ROOT + '/jam');
CleanDir(SCRATCH_ROOT + '/jam');
RoundTrip(mbfJam, SCRATCH_ROOT + '/jam/echo', 'JAM round-trip', 5);
ForceDirectories(SCRATCH_ROOT + '/squish');
CleanDir(SCRATCH_ROOT + '/squish');
RoundTrip(mbfSquish, SCRATCH_ROOT + '/squish/sq', 'Squish round-trip', 5);
ForceDirectories(SCRATCH_ROOT + '/msg');
RoundTrip(mbfMsg, SCRATCH_ROOT + '/msg/', 'FTS-1 MSG round-trip', 5);
ForceDirectories(SCRATCH_ROOT + '/goldbase');
RoundTrip(mbfGoldBase, SCRATCH_ROOT + '/goldbase/', 'GoldBase round-trip', 5);
Halt(TestsSummary);
end.