fpc/packages/fcl-db/tests/testdbexport.pas
Michaël Van Canneyt eb009243aa * PChar -> PansiChar
2023-07-15 18:22:41 +02:00

1185 lines
39 KiB
ObjectPascal

unit TestDBExport;
{
Unit tests which are common to all datasets. Tests export to various formats.
}
{$IFDEF FPC}
{$mode Delphi}{$H+}
{$ENDIF}
{$codepage utf8}
interface
uses
fpcunit, testregistry,
Classes, SysUtils, db, ToolsUnit, bufdataset,
fpDBExport,
fpXMLXSDExport,
fpdbfexport,
fpcsvexport,
fpfixedexport,
fpSimpleXMLExport,
fpsimplejsonexport,
fpSQLExport,
fptexexport,
fprtfexport;
type
TDetailedExportFormats = (efDBaseIII, efDBaseIV, efDBaseVII, efCSV, efFixedLengthText, efFoxpro,
efJSON, efRTF, efSQL, efTeX, efXML, efXMLXSDAccess, efXMLXSDADONet, efXMLXSDClientDataset,
efXMLXSDExcel, efVisualFoxpro);
const
TDetailedExportExtensions: array [TDetailedExportFormats] of string =
('.dbf','.dbf','.dbf','.csv','.txt','.dbf','.json','.rtf','.sql','.tex',
'.xml','.xml','.xml','.xml','.xml','.dbf'); //File extension for the corresponding TDetailedExportFormats
type
{ TTestDBExport }
TTestDBExport = class(TTestCase)
private
FExportTempDir: string; //directory where test files are placed
FKeepFilesAfterTest: boolean; //remove files after testing?
function FieldSupported(const FieldType: TFieldType;
const ExportSubFormat: TDetailedExportFormats): boolean; //Checks if output dataset supports a certain field type
procedure GenericExportTest(Exporter: TCustomDatasetExporter; ExportFormat: TDetailedExportFormats);
function GetABCDS: TBufDataset;
function GetBooleanDS: TBufDataset;
function GetFileSize(const FileName: string): integer; //Gets a file's size
function GetWideStringDS: TBufDataset;
protected
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestDBFExport_DBaseIV;
procedure TestDBFExport_DBaseVII;
procedure TestDBFExport_FoxPro;
procedure TestDBFExport_VisualFoxPro;
procedure TestCSVExport; //tests csv export with default values
procedure TestCSVExport_RFC4180WithHeader; //tests csv export with settings that match RFC4180
procedure TestCSVExport_TweakSettingsSemicolon; //tests semicolon delimited, custom country values
procedure TestCSVExportDisabledFields;
procedure TestFixedTextExport;
procedure TestFixedTextExportUTF8;
procedure TestFixedTextExportUTF16;
procedure TestFixedTextExportBoolean;
procedure TestFixedTextExportHeader;
procedure TestFixedTextExportHeaderDisabledFields;
procedure TestFixedTextExportSpaces;
procedure TestJSONExport;
procedure TestRTFExport;
procedure TestSQLExport;
procedure TestTeXExport;
procedure TestXMLExport; //tests simple xml export
procedure TestXMLExportSpecialChars;
procedure TestXSDExport_Access_NoXSD_DecimalOverride; //tests xmlxsd export
procedure TestXSDExport_Access_NoXSD_NoDecimalOverride; //tests xmlxsd export
procedure TestXSDExport_Access_XSD_DecimalOverride; //tests xmlxsd export
procedure TestXSDExport_Access_XSD_NoDecimalOverride; //tests xmlxsd export
procedure TestXSDExport_ADONET_NoXSD; //tests xmlxsd export
procedure TestXSDExport_ADONET_XSD; //tests xmlxsd export
procedure TestXSDExport_DelphiClientDataset; //tests xmlxsd export
procedure TestXSDExport_Excel; //tests xmlxsd export
end;
implementation
uses bufdatasettoolsunit, xmlread,dom;
function TTestDBExport.FieldSupported(const FieldType: TFieldType;
const ExportSubFormat: TDetailedExportFormats): boolean;
const
// Alphabetically sorted for quick review:
DBaseVIIUnsupported=[ftADT,ftArray,ftBCD,ftBytes,ftCurrency,ftCursor,ftDataSet,
ftFixedWideChar,
ftFMTBcd,ftFmtMemo,ftGraphic,ftGuid,ftIDispatch,ftInterface,ftLongWord,
ftOraBlob,ftOraClob,ftParadoxOle,ftReference,ftTime,ftTimeStamp,ftTypedBinary,
ftUnknown,ftVarBytes,ftVariant,ftWidememo,ftWideString];
FoxProUnsupported= [ftADT,ftArray, ftBytes, ftCursor,ftDataSet,
ftFixedWideChar,
ftFMTBcd,ftFmtMemo,ftGraphic,ftGuid,ftIDispatch,ftInterface,ftLongWord,
ftOraBlob,ftOraClob,ftParadoxOle,ftReference,ftTime,ftTimeStamp,ftTypedBinary,
ftUnknown,ftVarBytes,ftVariant,ftWideMemo,ftWideString];
begin
result:=true;
case ExportSubFormat of
efDBaseIII: if FieldType in DBaseVIIUnsupported+[ftAutoInc] then result:=false;
efDBaseIV: if FieldType in DBaseVIIUnsupported+[ftAutoInc] then result:=false;
efDBaseVII: if FieldType in DBaseVIIUnsupported then result:=false;
efCSV: result:=true;
efFixedLengthText: result:=true; //todo: verify if all fields are really supported. Quick glance would indicate so
efFoxpro: if FieldType in FoxProUnsupported then result:=false;
efVisualFoxpro: if FieldType in FoxProUnsupported-[ftVarBytes] then result:=false;
efJSON: result:=true;
efRTF: result:=true;
efSQL: result:=true;
efTeX: result:=true;
efXML: result:=true;
efXMLXSDAccess, efXMLXSDADONet, efXMLXSDClientDataset, efXMLXSDExcel: result:=true;
else
result:=false;
Fail('Error in test code itself: FieldSupported unknown ExportSubFormat '+inttostr(ord(ExportSubFormat)));
end;
end;
procedure TTestDBExport.GenericExportTest(Exporter: TCustomDatasetExporter; ExportFormat: TDetailedExportFormats);
var
FieldMapping: TExportFields;
NumberExported: integer;
i: integer;
begin
FieldMapping:=TExportFields.Create(Exporter.ExportFields.ItemClass);
try
Exporter.Dataset := DBConnector.GetFieldDataset;
Exporter.Dataset.Open;
Exporter.BuildDefaultFieldMap(FieldMapping);
// Remove unsupported data types in export from the mapping.
// Cannot use FieldMapping[i].Field.DataType as
// the field hasn't been set by BindFields yet... assume the
// order of original fields and their mapping match
for i:=Exporter.Dataset.Fields.Count-1 downto 0 do
begin
if not FieldSupported(
Exporter.Dataset.Fields[i].DataType,
ExportFormat) then
FieldMapping.Delete(i);
end;
for i:=0 to FieldMapping.Count-1 do
Exporter.ExportFields.Add.Assign(FieldMapping[i]);
NumberExported := Exporter.Execute;
Exporter.Dataset.Last;
Exporter.Dataset.First;
AssertEquals('Number of records exported matches recordcount', NumberExported,
Exporter.Dataset.RecordCount);
Exporter.Dataset.Close;
finally
FieldMapping.Free;
end;
end;
function TTestDBExport.GetFileSize(const FileName: string): integer;
Var
F : file of byte;
begin
result:=0;
assign (F,FileName);
try
reset(F);
result:=filesize(F);
finally
close(F);
end;
end;
procedure TTestDBExport.SetUp;
begin
inherited SetUp;
InitialiseDBConnector;
DBConnector.StartTest(TestName);
FExportTempDir:=IncludeTrailingPathDelimiter(ExpandFileName(''))+'exporttests'+PathDelim; //Store output in subdirectory
ForceDirectories(FExportTempDir);
FKeepFilesAfterTest:=true; //keep test files; consistent with other units right now
end;
procedure TTestDBExport.TearDown;
begin
inherited TearDown;
DBConnector.StopTest(TestName);
FreeDBConnector;
end;
procedure TTestDBExport.TestDBFExport_DBaseVII;
var
Exporter: TFPDBFExport;
ExportFormat: TDetailedExportFormats;
ExportSettings:TDBFExportFormatSettings;
begin
Exporter := TFPDBFExport.Create(nil);
ExportSettings:=TDBFExportFormatSettings.Create(true);
try
ExportFormat:=efDBaseVII;
ExportSettings.TableFormat:=tfDBaseVII;
ExportSettings.AutoRenameFields:=true; //rename conflicting column names
// Use export subtype position to differentiate output filenames:
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestDBFExport_DBaseIV;
var
Exporter: TFPDBFExport;
ExportFormat: TDetailedExportFormats;
ExportSettings:TDBFExportFormatSettings;
begin
Exporter := TFPDBFExport.Create(nil);
ExportSettings:=TDBFExportFormatSettings.Create(true);
try
ExportFormat:=efDBaseIV;
ExportSettings.TableFormat:=tfDBaseIV;
ExportSettings.AutoRenameFields:=true; //rename conflicting column names
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestDBFExport_FoxPro;
var
Exporter: TFPDBFExport;
ExportFormat: TDetailedExportFormats;
ExportSettings:TDBFExportFormatSettings;
begin
Exporter := TFPDBFExport.Create(nil);
ExportSettings:=TDBFExportFormatSettings.Create(true);
try
ExportFormat:=efFoxpro;
ExportSettings.TableFormat:=tfFoxPro;
ExportSettings.AutoRenameFields:=true; //rename conflicting column names
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestDBFExport_VisualFoxPro;
var
Exporter: TFPDBFExport;
ExportFormat: TDetailedExportFormats;
ExportSettings:TDBFExportFormatSettings;
begin
Exporter := TFPDBFExport.Create(nil);
ExportSettings:=TDBFExportFormatSettings.Create(true);
try
ExportFormat:=efVisualFoxpro;
ExportSettings.TableFormat:=tfVisualFoxPro;
ExportSettings.AutoRenameFields:=true; //rename conflicting column names
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestXSDExport_Access_NoXSD_DecimalOverride;
var
Exporter: TXMLXSDExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TXMLXSDFormatSettings;
begin
Exporter := TXMLXSDExporter.Create(nil);
ExportSettings:=TXMLXSDFormatSettings.Create(true);
try
ExportSettings.ExportFormat:=AccessCompatible;
ExportFormat:=efXMLXSDAccess;
ExportSettings.CreateXSD:=false;
ExportSettings.DecimalSeparator:='.'; //override
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestXSDExport_Access_NoXSD_NoDecimalOverride;
var
Exporter: TXMLXSDExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TXMLXSDFormatSettings;
begin
Exporter := TXMLXSDExporter.Create(nil);
ExportSettings:=TXMLXSDFormatSettings.Create(true);
try
ExportSettings.ExportFormat:=AccessCompatible;
ExportFormat:=efXMLXSDAccess;
ExportSettings.CreateXSD:=false;
ExportSettings.DecimalSeparator:=#0; //don't override
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestXSDExport_Access_XSD_DecimalOverride;
var
Exporter: TXMLXSDExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TXMLXSDFormatSettings;
begin
Exporter := TXMLXSDExporter.Create(nil);
ExportSettings:=TXMLXSDFormatSettings.Create(true);
try
ExportSettings.ExportFormat:=AccessCompatible;
ExportFormat:=efXMLXSDAccess;
ExportSettings.CreateXSD:=true;
ExportSettings.DecimalSeparator:='.'; //override
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestXSDExport_Access_XSD_NoDecimalOverride;
var
Exporter: TXMLXSDExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TXMLXSDFormatSettings;
begin
Exporter := TXMLXSDExporter.Create(nil);
ExportSettings:=TXMLXSDFormatSettings.Create(true);
try
ExportSettings.ExportFormat:=AccessCompatible;
ExportFormat:=efXMLXSDAccess;
ExportSettings.CreateXSD:=true;
ExportSettings.DecimalSeparator:=AnsiChar(#0); //don't override
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestXSDExport_ADONET_NoXSD;
var
Exporter: TXMLXSDExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TXMLXSDFormatSettings;
begin
Exporter := TXMLXSDExporter.Create(nil);
ExportSettings:=TXMLXSDFormatSettings.Create(true);
try
ExportSettings.ExportFormat:=ADONETCompatible;
ExportFormat:=efXMLXSDADONet;
ExportSettings.CreateXSD:=false;
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestXSDExport_ADONET_XSD;
var
Exporter: TXMLXSDExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TXMLXSDFormatSettings;
begin
Exporter := TXMLXSDExporter.Create(nil);
ExportSettings:=TXMLXSDFormatSettings.Create(true);
try
ExportSettings.ExportFormat:=ADONETCompatible;
ExportFormat:=efXMLXSDADONet;
ExportSettings.CreateXSD:=true;
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestCSVExport;
var
Exporter: TCSVExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings: TCSVFormatSettings;
begin
Exporter := TCSVExporter.Create(nil);
ExportSettings:=TCSVFormatSettings.Create(true);
try
ExportFormat:=efCSV;
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestCSVExport_RFC4180WithHeader;
var
Exporter: TCSVExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings: TCSVFormatSettings;
begin
Exporter := TCSVExporter.Create(nil);
ExportSettings:=TCSVFormatSettings.Create(true);
try
ExportSettings.FieldDelimiter:=','; //RFC 4180 specified commas as delimiter
ExportSettings.HeaderRow:=true; //...allows an optional header line
ExportSettings.QuoteChar:='"'; //...requires quoting with " (if quoting)
// Fields containing line breaks (CRLF), double quotes,
// and commas should be enclosed in double-quotes.
// => this probably won't get tested with this test set.
ExportFormat:=efCSV;
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestCSVExport_TweakSettingsSemicolon;
var
Exporter: TCSVExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings: TCSVFormatSettings;
begin
Exporter := TCSVExporter.Create(nil);
ExportSettings:=TCSVFormatSettings.Create(true);
try
ExportSettings.FieldDelimiter:=';';
ExportSettings.QuoteChar:='"'; //try explicit assignment
ExportSettings.RowDelimiter:=#10; //Unix/Linux format
ExportSettings.BooleanFalse:='onwaar'; //why not a Dutch output format?
ExportSettings.BooleanTrue:='waar'; //why not a Dutch output format?
ExportSettings.CurrencyDigits:=3;
ExportSettings.CurrencySymbol:='€'; //euro sign
ExportSettings.DateFormat:='d-mm-yyyy'; //Dutch setting
ExportSettings.DateTimeFormat:='d-mm-yyyy hh:nn:ss'; //Dutch setting
ExportSettings.DecimalSeparator:=','; //another Dutch setting
ExportSettings.TimeFormat:='hh:nn:ss'; //Dutch setting
ExportSettings.IntegerFormat:='0000';//Strange but nice ;)
ExportFormat:=efCSV;
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestCSVExportDisabledFields;
var
DS : TBufDataset;
Exporter: TCSVExporter;
F : text;
S : UTF8String;
haveFile : Boolean;
begin
haveFile:=False;
Exporter:=Nil;
DS:=GetABCDS;
try
Exporter := TCSVExporter.Create(nil);
Exporter.FormatSettings.HeaderRow:=True;
Exporter.Dataset:=DS;
Exporter.FileName := FExportTempDir + lowercase(TestName) + '.csv';
Exporter.BuildDefaultFieldMap(Exporter.ExportFields);
Exporter.ExportFields[1].Enabled:=False;
AssertEquals('Output count',2,Exporter.Execute);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
AssignFile(F,Exporter.FileName);
Reset(F);
haveFile:=True;
Readln(F,S);
AssertEquals('Correct header line','A,C',S); // 1 extra
Readln(F,S);
AssertEquals('Correct first line','xx,zz',S); // 1 extra
Readln(F,S);
AssertEquals('Correct first line','x,z',S); // 1 extra
finally
if HaveFile then
closeFile(F);
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
Exporter.Free;
end;
end;
procedure TTestDBExport.TestFixedTextExport;
var
Exporter: TFixedLengthExporter;
ExportFormat: TDetailedExportFormats;
begin
Exporter := TFixedLengthExporter.Create(nil);
try
ExportFormat:=efFixedLengthText;
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
Exporter.Free;
end;
end;
Const
// UTF8 code page assumed !
WidestringLine1 = '这是一个测验';
WidestringLine2 = 'Это тест.';
WidestringLine3 = 'ça roule.';
WidestringResLine1 = '这是一';
WidestringResLine2 = 'Это';
WidestringResLine3 = 'ça ';
Function TTestDBExport.GetWideStringDS : TBufDataset;
Var
DS : TBufDataset;
begin
DS:=TPersistentBufDataset.Create(Nil);
try
DS.FieldDefs.Add('F',ftWideString,10);
DS.CreateDataset;
DS.Append;
DS.Fields[0].AsWideString:=UTF8Decode(WideStringLine1);
DS.Post;
DS.Append;
DS.Fields[0].AsWideString:=UTF8Decode(WideStringLine2);
DS.Post;
DS.Append;
DS.Fields[0].AsWideString:=UTF8Decode(WideStringLine3);
DS.Post;
DS.First;
except
DS.Free;
Raise;
end;
Result:=DS;
end;
procedure TTestDBExport.TestFixedTextExportUTF8;
var
DS : TBufDataset;
Exporter: TFixedLengthExporter;
F : text;
S : UTF8String;
haveFile : Boolean;
begin
haveFile:=False;
Exporter:=Nil;
DS:=GetWideStringDS;
try
Exporter := TFixedLengthExporter.Create(nil);
Exporter.Dataset:=DS;
Exporter.FormatSettings.CharMode:=cmUTF8;
Exporter.FileName := FExportTempDir + lowercase(TestName) + '.txt';
Exporter.BuildDefaultFieldMap(Exporter.ExportFields);
TFixedLengthExportFieldItem(Exporter.ExportFields[0]).Width:=3;
AssertEquals('Output count',3,Exporter.Execute);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
AssignFile(F,Exporter.FileName);
Reset(F);
haveFile:=True;
Readln(F,S);
AssertEquals('Correct first line',UTF8Decode(WideStringResLine1),UTF8Decode(S));
Readln(F,S);
AssertEquals('Correct second line',UTF8Decode(WideStringResLine2),UTF8Decode(S));
Readln(F,S);
AssertEquals('Correct second line',UTF8Decode(WideStringResLine3),UTF8Decode(S));
finally
if HaveFile then
closeFile(F);
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
Exporter.Free;
end;
end;
procedure TTestDBExport.TestFixedTextExportUTF16;
var
DS : TBufDataset;
Exporter: TFixedLengthExporter;
F : text;
S : UnicodeString;
haveFile : Boolean;
begin
haveFile:=False;
Exporter:=Nil;
DS:=GetWideStringDS;
try
Exporter := TFixedLengthExporter.Create(nil);
Exporter.Dataset:=DS;
Exporter.FormatSettings.CharMode:=cmUTF16;
Exporter.FileName := FExportTempDir + lowercase(TestName) + '.txt';
Exporter.BuildDefaultFieldMap(Exporter.ExportFields);
TFixedLengthExportFieldItem(Exporter.ExportFields[0]).Width:=3;
AssertEquals('Output count',3,Exporter.Execute);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
AssignFile(F,Exporter.FileName);
Reset(F);
haveFile:=True;
Readln(F,S);
AssertEquals('Correct first line',UTF8Decode(WideStringResLine1),S);
Readln(F,S);
AssertEquals('Correct second line',UTF8Decode(WideStringResLine2),S);
Readln(F,S);
AssertEquals('Correct second line',UTF8Decode(WideStringResLine3),S);
finally
if HaveFile then
closeFile(F);
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
Exporter.Free;
end;
end;
Function TTestDBExport.GetBooleanDS : TBufDataset;
Var
DS : TBufDataset;
begin
DS:=TPersistentBufDataSet.Create(Nil);
try
DS.FieldDefs.Add('F',ftBoolean,0);
DS.CreateDataset;
DS.Append;
DS.Fields[0].AsBoolean:=true;
DS.Post;
DS.Append;
DS.Fields[0].AsBoolean:=False;
DS.Post;
DS.First;
except
DS.Free;
Raise;
end;
Result:=DS;
end;
Function TTestDBExport.GetABCDS : TBufDataset;
Var
DS : TBufDataset;
begin
DS:=TPersistentBufDataset.Create(Nil);
try
DS.FieldDefs.Add('A',ftString,2);
DS.FieldDefs.Add('B',ftString,2);
DS.FieldDefs.Add('C',ftString,2);
DS.CreateDataset;
DS.Append;
DS.Fields[0].AsString:='xx';
DS.Fields[1].AsString:='y';
DS.Fields[2].AsString:='zz';
DS.Post;
DS.Append;
DS.Fields[0].AsString:='x';
DS.Fields[1].AsString:='yy';
DS.Fields[2].AsString:='z';
DS.Post;
DS.First;
except
DS.Free;
Raise;
end;
Result:=DS;
end;
procedure TTestDBExport.TestFixedTextExportBoolean;
var
DS : TBufDataset;
Exporter: TFixedLengthExporter;
F : text;
S : UTF8String;
haveFile : Boolean;
begin
haveFile:=False;
Exporter:=Nil;
DS:=GetBooleanDS;
try
Exporter := TFixedLengthExporter.Create(nil);
Exporter.FormatSettings.BooleanFalse:='false';
Exporter.FormatSettings.BooleanTrue:='True';
Exporter.Dataset:=DS;
Exporter.FileName := FExportTempDir + lowercase(TestName) + '.txt';
Exporter.BuildDefaultFieldMap(Exporter.ExportFields);
AssertEquals('Correct width',5, TFixedLengthExportFieldItem(Exporter.ExportFields[0]).Width);
AssertEquals('Output count',2,Exporter.Execute);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
AssignFile(F,Exporter.FileName);
Reset(F);
haveFile:=True;
Readln(F,S);
AssertEquals('Correct first line','True ',S); // 1 extra
Readln(F,S);
AssertEquals('Correct second line','false',S);
finally
if HaveFile then
closeFile(F);
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
Exporter.Free;
end;
end;
procedure TTestDBExport.TestFixedTextExportHeader;
var
DS : TBufDataset;
Exporter: TFixedLengthExporter;
F : text;
S : UTF8String;
haveFile : Boolean;
begin
haveFile:=False;
Exporter:=Nil;
DS:=GetABCDS;
try
Exporter := TFixedLengthExporter.Create(nil);
Exporter.FormatSettings.BooleanFalse:='false';
Exporter.FormatSettings.BooleanTrue:='True';
Exporter.FormatSettings.HeaderRow:=True;
Exporter.Dataset:=DS;
Exporter.FileName := FExportTempDir + lowercase(TestName) + '.txt';
Exporter.BuildDefaultFieldMap(Exporter.ExportFields);
AssertEquals('Correct width',2, TFixedLengthExportFieldItem(Exporter.ExportFields[0]).Width);
AssertEquals('Output count',2,Exporter.Execute);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
AssignFile(F,Exporter.FileName);
Reset(F);
haveFile:=True;
Readln(F,S);
AssertEquals('Correct header line','A B C ',S); // 1 extra
Readln(F,S);
AssertEquals('Correct first line','xxy zz',S); // 1 extra
Readln(F,S);
AssertEquals('Correct second line','x yyz ',S);
finally
if HaveFile then
closeFile(F);
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
Exporter.Free;
end;
end;
procedure TTestDBExport.TestFixedTextExportHeaderDisabledFields;
var
DS : TBufDataset;
Exporter: TFixedLengthExporter;
F : text;
S : UTF8String;
haveFile : Boolean;
begin
haveFile:=False;
Exporter:=Nil;
DS:=GetABCDS;
try
Exporter := TFixedLengthExporter.Create(nil);
Exporter.FormatSettings.HeaderRow:=True;
Exporter.Dataset:=DS;
Exporter.FileName := FExportTempDir + lowercase(TestName) + '.txt';
Exporter.BuildDefaultFieldMap(Exporter.ExportFields);
Exporter.ExportFields[1].Enabled:=False;
AssertEquals('Output count',2,Exporter.Execute);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
AssignFile(F,Exporter.FileName);
Reset(F);
haveFile:=True;
Readln(F,S);
AssertEquals('Correct header line','A C ',S); // 1 extra
Readln(F,S);
AssertEquals('Correct first line','xxzz',S); // 1 extra
Readln(F,S);
AssertEquals('Correct first line','x z ',S); // 1 extra
finally
if HaveFile then
closeFile(F);
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
Exporter.Free;
end;
end;
procedure TTestDBExport.TestFixedTextExportSpaces;
var
DS : TBufDataset;
Exporter: TFixedLengthExporter;
F : text;
S : UTF8String;
haveFile : Boolean;
begin
haveFile:=False;
Exporter:=Nil;
DS:=GetABCDS;
try
Exporter := TFixedLengthExporter.Create(nil);
Exporter.FormatSettings.BooleanFalse:='false';
Exporter.FormatSettings.BooleanTrue:='True';
Exporter.FormatSettings.HeaderRow:=True;
Exporter.FormatSettings.ColumnSeparatorSpaceCount:=2;
Exporter.Dataset:=DS;
Exporter.FileName := FExportTempDir + lowercase(TestName) + '.txt';
Exporter.BuildDefaultFieldMap(Exporter.ExportFields);
AssertEquals('Output count',2,Exporter.Execute);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
AssignFile(F,Exporter.FileName);
Reset(F);
haveFile:=True;
Readln(F,S);
AssertEquals('Correct header line','A B C ',S); // 1 extra
Readln(F,S);
AssertEquals('Correct first line','xx y zz',S); // 1 extra
Readln(F,S);
AssertEquals('Correct first line','x yy z ',S); // 1 extra
finally
if HaveFile then
closeFile(F);
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
Exporter.Free;
end;
end;
procedure TTestDBExport.TestJSONExport;
var
Exporter: TSimpleJSONExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TSimpleJSONFormatSettings;
begin
Exporter := TSimpleJSONExporter.Create(nil);
ExportSettings:=TSimpleJSONFormatSettings.Create(true);
try
ExportFormat:=efJSON;
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) + lowercase(rightstr(TestName,5))+
inttostr(ord(ExportFormat))+
TDetailedExportExtensions[ExportFormat]; Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestRTFExport;
var
Exporter: TRTFExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TRTFExportFormatSettings;
begin
Exporter := TRTFExporter.Create(nil);
ExportSettings:=TRTFExportFormatSettings.Create(true);
try
ExportFormat:=efRTF;
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5))+
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestSQLExport;
var
Exporter: TSQLExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TSQLFormatSettings;
begin
Exporter := TSQLExporter.Create(nil);
ExportSettings:=TSQLFormatSettings.Create(true);
try
ExportSettings.TableName:='ATABLE'; //required for export to succeed
ExportFormat:=efSQL;
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5))+
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestTeXExport;
var
Exporter: TTexExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TTeXExportFormatSettings;
begin
Exporter := TTexExporter.Create(nil);
ExportSettings:=TTeXExportFormatSettings.Create(true);
try
ExportFormat:=efTeX;
Exporter.FileName := FExportTempDir +
inttostr(ord(ExportFormat)) + lowercase(rightstr(TestName,5))+
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestXMLExport;
var
Exporter: TSimpleXMLExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TSimpleXMLFormatSettings;
begin
Exporter := TSimpleXMLExporter.Create(nil);
ExportSettings:=TSimpleXMLFormatSettings.Create(true);
try
ExportFormat:=efXML;
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestXMLExportSpecialChars;
var
Exporter: TSimpleXMLExporter;
FieldMapping: TExportFields;
NumberExported: integer;
i: integer;
XML : TXMLDocument;
begin
XML:=Nil;
Exporter := TSimpleXMLExporter.Create(nil);
FieldMapping:=TExportFields.Create(Exporter.ExportFields.ItemClass);
try
Exporter.Dataset := DBConnector.GetFieldDataset;
Exporter.Dataset.Open;
Exporter.Dataset.Edit;
Exporter.Dataset.FieldByName('FString').AsString:='*&*<*>*';
Exporter.Dataset.Post;
Exporter.BuildDefaultFieldMap(FieldMapping);
Exporter.FileName := FExportTempDir + lowercase(rightstr(TestName,5)) + TDetailedExportExtensions[efXML];
for i:=Exporter.Dataset.Fields.Count-1 downto 0 do
begin
if not FieldSupported(
Exporter.Dataset.Fields[i].DataType,
efXML) then
FieldMapping.Delete(i);
end;
for i:=0 to FieldMapping.Count-1 do
Exporter.ExportFields.Add.Assign(FieldMapping[i]);
NumberExported := Exporter.Execute;
Exporter.Dataset.Last;
Exporter.Dataset.First;
AssertEquals('Number of records exported matches recordcount', NumberExported,
Exporter.Dataset.RecordCount);
Exporter.Dataset.Close;
ReadXMLFile(XML,Exporter.FileName);
AssertEquals('Correct written','*&*<*>*',XML.DocumentElement.FirstChild.FirstChild.NextSibling.FirstChild.NodeValue);
finally
XML.Free;
FieldMapping.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestXSDExport_DelphiClientDataset;
var
Exporter: TXMLXSDExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TXMLXSDFormatSettings;
begin
Exporter := TXMLXSDExporter.Create(nil);
ExportSettings:=TXMLXSDFormatSettings.Create(true);
try
ExportSettings.ExportFormat:=DelphiClientDataset;
ExportFormat:=efXMLXSDClientDataset;
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
procedure TTestDBExport.TestXSDExport_Excel;
var
Exporter: TXMLXSDExporter;
ExportFormat: TDetailedExportFormats;
ExportSettings:TXMLXSDFormatSettings;
begin
Exporter := TXMLXSDExporter.Create(nil);
ExportSettings:=TXMLXSDFormatSettings.Create(true);
try
ExportSettings.ExportFormat:=ExcelCompatible;
ExportFormat:=efXMLXSDExcel;
Exporter.FileName := FExportTempDir + inttostr(ord(ExportFormat)) +
lowercase(rightstr(TestName,5)) +
TDetailedExportExtensions[ExportFormat];
Exporter.FormatSettings:=ExportSettings;
GenericExportTest(Exporter, ExportFormat);
AssertTrue('Output file must be created', FileExists(Exporter.FileName));
AssertFalse('Output file must not be empty', (GetFileSize(Exporter.FileName) = 0));
finally
if (FKeepFilesAfterTest = False) then
DeleteFile(Exporter.FileName);
ExportSettings.Free;
Exporter.Free;
end;
end;
initialization
RegisterTest(TTestDBExport);
end.