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}).
135 lines
4.1 KiB
ObjectPascal
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.
|