Browse Source

* Applied patch from #22899

git-svn-id: trunk@22401 -
michael 13 years ago
parent
commit
3f803013a3

+ 30 - 3
packages/fcl-db/tests/README.txt

@@ -2,7 +2,7 @@ This directory contains a framework to test several TDataset descendents.
 A lot of these tests are only applicable for SQL databases, but there are several tests that also apply to other objects, such as TBufDataset.
 A lot of these tests are only applicable for SQL databases, but there are several tests that also apply to other objects, such as TBufDataset.
 
 
 The framework is based on the fpcunit unit test system. The tests can be
 The framework is based on the fpcunit unit test system. The tests can be
-executed using any fpcunit-testrunner. For example the console and graphical
+executed using any fpcunit testrunner. For example the console and graphical
 fpcunit test runners from Lazarus.
 fpcunit test runners from Lazarus.
 Simply add the test* units in this directory to the uses statement of the
 Simply add the test* units in this directory to the uses statement of the
 test runner and all tests will get registered and executed.
 test runner and all tests will get registered and executed.
@@ -10,6 +10,8 @@ test runner and all tests will get registered and executed.
 A simple test runner (dbtestframework.pas) which generates XML output is
 A simple test runner (dbtestframework.pas) which generates XML output is
 included in this directory.
 included in this directory.
 
 
+DBTestframework architecture
+============================
 To test a TDataset descendent, a 'connector' is needed to test the database.
 To test a TDataset descendent, a 'connector' is needed to test the database.
 To add a new connector, create a new *toolsunit.pas file, then add it to 
 To add a new connector, create a new *toolsunit.pas file, then add it to 
 the uses section in 'dbtestframework.pas'. Several connectors are available 
 the uses section in 'dbtestframework.pas'. Several connectors are available 
@@ -29,11 +31,36 @@ They call InternalGetNDataset and InternalGetFieldDataset which should be implem
 Toolsunit.pas defines some variables for use, e.g. testValuesCount is the number of records/test values in the FieldDataset dataset; MaxDataset is the same for NDataset.
 Toolsunit.pas defines some variables for use, e.g. testValuesCount is the number of records/test values in the FieldDataset dataset; MaxDataset is the same for NDataset.
 See e.g. the SQLDBToolsUnit for the implementation for SQL Databases.
 See e.g. the SQLDBToolsUnit for the implementation for SQL Databases.
 
 
+Tests
+=====
+In your tests, you can specify that you only want to run for certain groups/connectors.
+E.g. this example to only run for Bufdataset tests:
+  TTestSpecificTBufDataset = class(TTestCase)
+  ...
+initialization  
+  if uppercase(dbconnectorname)='BUFDATASET' then
+    begin
+    RegisterTestDecorator(TDBBasicsTestSetup, TTestSpecificTBufDataset);
+    end;
+
+Specifying databases, connector names
+=====================================
 Which connector is currently used is dependent on the 'database.ini'
 Which connector is currently used is dependent on the 'database.ini'
 configuration file. Also some settings which are connector-dependent can be set
 configuration file. Also some settings which are connector-dependent can be set
 in that file. See 'database.ini.txt' for an example.
 in that file. See 'database.ini.txt' for an example.
 
 
-I hope this is enough information to get you started,
+The connector names to be used are derived from the connector classes.
+
+For example, the SQL RDBMS connector defined in sqldbtoolsunit:
+- it has this class definition
+TSQLDBConnector = class(TDBConnector)
+- its name in database.ini is sqldb (
+- incidentally, in databases.ini, more parameter such as
+connectorparams=postgresql (which specify db type) are needed
+The parameters use depend on the connector type (sql,...)
+
+If you specify the wrong (or no) name (or don't have database.ini), you will get an exception in your test runner:
+Unknown db connector specified
 
 
 Joost van der Sluis (30-12-2006), 
 Joost van der Sluis (30-12-2006), 
-amended by Reinier Olislagers (April 2012)
+amended by Reinier Olislagers (2012)

+ 7 - 1
packages/fcl-db/tests/database.ini.txt

@@ -3,7 +3,7 @@
 ; Select here which section has to be used currently, 
 ; Select here which section has to be used currently, 
 ; i.e. which database you want to use
 ; i.e. which database you want to use
 [Database]
 [Database]
-type=interbase
+type=bufdataset
 
 
 
 
 ; These sections are for the several SQLDB-types of databases:
 ; These sections are for the several SQLDB-types of databases:
@@ -117,3 +117,9 @@ connector=memds
 ; BufDataset in memory dataset:
 ; BufDataset in memory dataset:
 [bufdataset]
 [bufdataset]
 connector=bufdataset
 connector=bufdataset
+
+; sdfdataset file-based dataset:
+[sdfdataset]
+connector=sdfds
+; subdirectory for the sdf files:
+name=sdftest

+ 2 - 2
packages/fcl-db/tests/dbtestframework.pas

@@ -11,14 +11,14 @@ uses
   fpcunit,  testreport, testregistry,
   fpcunit,  testreport, testregistry,
   DigestTestReport,
   DigestTestReport,
   toolsunit,
   toolsunit,
-// List of supported database-connectors
+// List of supported database connectors
   sqldbtoolsunit,
   sqldbtoolsunit,
   dbftoolsunit,
   dbftoolsunit,
   bufdatasettoolsunit,
   bufdatasettoolsunit,
   memdstoolsunit,
   memdstoolsunit,
   SdfDSToolsUnit,
   SdfDSToolsUnit,
   tcsdfdata,
   tcsdfdata,
-// Units wich contains the tests
+// Units wich contain the tests
   TestBasics,
   TestBasics,
   TestFieldTypes,
   TestFieldTypes,
   TestDatasources,
   TestDatasources,

+ 21 - 2
packages/fcl-db/tests/dbtestframework_gui.lpi

@@ -7,7 +7,6 @@
       <MainUnit Value="0"/>
       <MainUnit Value="0"/>
       <ResourceType Value="res"/>
       <ResourceType Value="res"/>
       <UseXPManifest Value="True"/>
       <UseXPManifest Value="True"/>
-      <Icon Value="0"/>
     </General>
     </General>
     <i18n>
     <i18n>
       <EnableI18N LFM="False"/>
       <EnableI18N LFM="False"/>
@@ -15,8 +14,23 @@
     <VersionInfo>
     <VersionInfo>
       <StringTable ProductVersion=""/>
       <StringTable ProductVersion=""/>
     </VersionInfo>
     </VersionInfo>
-    <BuildModes Count="1">
+    <BuildModes Count="2">
       <Item1 Name="Default" Default="True"/>
       <Item1 Name="Default" Default="True"/>
+      <Item2 Name="debug">
+        <CompilerOptions>
+          <Version Value="11"/>
+          <SearchPaths>
+            <IncludeFiles Value="$(ProjOutDir)"/>
+            <OtherUnitFiles Value="../src/base;../src/sqldb/odbc;../src/sqldb/mssql;../src/sqldb/sqlite;../src/sqldb/postgres;../src/sqldb/oracle;../src/memds;../src/sqldb;../src/sqldb/interbase;../src/sqldb/mysql;../src/dbase;../src/sdf"/>
+          </SearchPaths>
+          <Other>
+            <CompilerMessages>
+              <UseMsgFile Value="True"/>
+            </CompilerMessages>
+            <CompilerPath Value="$(CompPath)"/>
+          </Other>
+        </CompilerOptions>
+      </Item2>
     </BuildModes>
     </BuildModes>
     <PublishOptions>
     <PublishOptions>
       <Version Value="2"/>
       <Version Value="2"/>
@@ -53,6 +67,11 @@
       <IncludeFiles Value="$(ProjOutDir)"/>
       <IncludeFiles Value="$(ProjOutDir)"/>
       <OtherUnitFiles Value="../src/base;../src/sqldb/odbc;../src/sqldb/mssql;../src/sqldb/sqlite;../src/sqldb/postgres;../src/sqldb/oracle;../src/memds;../src/sqldb;../src/sqldb/interbase;../src/sqldb/mysql;../src/dbase;../src/sdf"/>
       <OtherUnitFiles Value="../src/base;../src/sqldb/odbc;../src/sqldb/mssql;../src/sqldb/sqlite;../src/sqldb/postgres;../src/sqldb/oracle;../src/memds;../src/sqldb;../src/sqldb/interbase;../src/sqldb/mysql;../src/dbase;../src/sdf"/>
     </SearchPaths>
     </SearchPaths>
+    <Linking>
+      <Debugging>
+        <GenerateDebugInfo Value="False"/>
+      </Debugging>
+    </Linking>
     <Other>
     <Other>
       <CompilerMessages>
       <CompilerMessages>
         <UseMsgFile Value="True"/>
         <UseMsgFile Value="True"/>

+ 3 - 2
packages/fcl-db/tests/dbtestframework_gui.lpr

@@ -11,14 +11,15 @@ program dbtestframework_gui;
 
 
 uses
 uses
   Interfaces, Forms, GuiTestRunner,
   Interfaces, Forms, GuiTestRunner,
-  // Generic DB-testframework units
+  // Generic DB test framework units
   ToolsUnit,
   ToolsUnit,
-  // Connecors for different database-types
+  // Connectors for different database-types
   sqldbtoolsunit,
   sqldbtoolsunit,
   dbftoolsunit,
   dbftoolsunit,
   bufdatasettoolsunit,
   bufdatasettoolsunit,
   memdstoolsunit,
   memdstoolsunit,
   SdfDSToolsUnit,
   SdfDSToolsUnit,
+  tcsdfdata,
   // DB unittest
   // DB unittest
   testbasics,
   testbasics,
   TestFieldTypes,
   TestFieldTypes,

+ 6 - 0
packages/fcl-db/tests/sdfdstoolsunit.pas

@@ -46,11 +46,14 @@ end;
 procedure TSdfDSDBConnector.CreateNDatasets;
 procedure TSdfDSDBConnector.CreateNDatasets;
 var countID,n : integer;
 var countID,n : integer;
 begin
 begin
+  if dbname='' then raise Exception.Create('dbname variable not specified. You must specify name= in database.ini');
   for n := 0 to MaxDataSet do
   for n := 0 to MaxDataSet do
     begin
     begin
     with TSdfDataSet.Create(nil) do
     with TSdfDataSet.Create(nil) do
       begin
       begin
       FileName := dbname+PathDelim+'fpdev_'+inttostr(n)+'.dat';
       FileName := dbname+PathDelim+'fpdev_'+inttostr(n)+'.dat';
+      // Make sure the directory exists so we can write
+      ForceDirectories(dbname);
       DeleteFile(FileName);
       DeleteFile(FileName);
       FileMustExist:=False;
       FileMustExist:=False;
       
       
@@ -78,10 +81,13 @@ end;
 procedure TSdfDSDBConnector.CreateFieldDataset;
 procedure TSdfDSDBConnector.CreateFieldDataset;
 var i : integer;
 var i : integer;
 begin
 begin
+  if dbname='' then raise Exception.Create('dbname variable not specified. You must specify name= in database.ini');
   with TSdfDataSet.Create(nil) do
   with TSdfDataSet.Create(nil) do
     begin
     begin
     FileName := dbname+PathDelim+'fpdev_field.dat';
     FileName := dbname+PathDelim+'fpdev_field.dat';
       DeleteFile(FileName);
       DeleteFile(FileName);
+    // Make sure the directory exists so we can write
+    ForceDirectories(dbname);
     FileMustExist:=False;
     FileMustExist:=False;
     
     
     SetFieldDatasetSchema(Schema);
     SetFieldDatasetSchema(Schema);

+ 118 - 12
packages/fcl-db/tests/tcsdfdata.pp

@@ -1,24 +1,28 @@
 unit tcsdfdata;
 unit tcsdfdata;
-// Tests multiline functionality of sdfdataset
+// Tests specific functionality of sdfdataset (multiline etc)
 
 
 {$mode objfpc}{$H+}
 {$mode objfpc}{$H+}
 
 
 interface
 interface
 
 
 uses
 uses
-  Classes, SysUtils, Fpcunit, Testutils, Testregistry,
-  dateutils, sdfdata;
+  Classes, SysUtils, Fpcunit, Testutils, Testregistry, testdecorator,
+  dateutils,sdfdata,ToolsUnit;
 
 
 type
 type
 
 
-  { Ttestexport1 }
+  { Ttestsdfspecific }
 
 
-  Ttestexport1 = class(Ttestcase)
+  Ttestsdfspecific = class(Ttestcase)
   protected
   protected
     TestDataset: TSDFDataset;
     TestDataset: TSDFDataset;
     procedure Setup; override;
     procedure Setup; override;
     procedure Teardown; override;
     procedure Teardown; override;
   published
   published
+    procedure TestEmptyFileHeader;
+    procedure TestEmptyFileNoHeader;
+    procedure TestSingleLineHeader;
+    procedure TestSingleLineNoHeader;
     procedure TestOutput;
     procedure TestOutput;
     procedure TestInputOurFormat;
     procedure TestInputOurFormat;
     procedure TestDelimitedTextOutput;
     procedure TestDelimitedTextOutput;
@@ -26,7 +30,104 @@ type
 
 
 implementation
 implementation
 
 
-procedure Ttestexport1.TestOutput;
+procedure Ttestsdfspecific.TestEmptyFileHeader;
+// An empty file should return 0 records even if it has a header
+const
+  InputFilename='empty.csv';
+begin
+  TestDataSet.Close;
+
+  if FileExists(InputFilename) then DeleteFile(InputFilename);
+  TestDataset.FileMustExist:=false;
+  TestDataset.FirstLineAsSchema := True;  
+  TestDataset.FileName:=InputFilename;
+  TestDataset.Open;
+
+  TestDataset.Last;
+  TestDataset.First;  
+  AssertEquals('Number of records in test dataset', 0, TestDataset.RecordCount);
+  TestDataset.Close;
+end;
+
+procedure Ttestsdfspecific.TestEmptyFileNoHeader;
+// An empty file should return 0 records even if it has a header
+const
+  InputFilename='empty.csv';
+begin
+  TestDataSet.Close;
+
+  if FileExists(InputFilename) then DeleteFile(InputFilename);
+  TestDataset.FileMustExist:=false;
+  TestDataset.FirstLineAsSchema := false;  
+  TestDataset.FileName:=InputFilename;
+  TestDataset.Open;
+
+  TestDataset.Last;
+  TestDataset.First;  
+  AssertEquals('Number of records in test dataset', 0, TestDataset.RecordCount);
+  TestDataset.Close;
+end;
+
+procedure Ttestsdfspecific.TestSingleLineHeader;
+// A file with a single data line and header should return 1 records
+const
+  InputFilename='singleh.csv';
+var
+  FileStrings: TStringList;
+begin
+  TestDataSet.Close;
+
+  if FileExists(InputFilename) then DeleteFile(InputFilename);
+  FileStrings:=TStringList.Create;
+  try
+    FileStrings.Add('ID,NAME,BIRTHDAY');
+    FileStrings.Add('1,SimpleName,31-12-1976');
+    FileStrings.SaveToFile(InputFileName);
+  finally
+    FileStrings.Free;
+  end;
+
+  TestDataset.FileMustExist:=false;
+  TestDataset.FirstLineAsSchema := true;
+  TestDataset.FileName:=InputFilename;
+  TestDataset.Open;
+
+  TestDataset.Last;
+  TestDataset.First;
+  AssertEquals('Number of records in test dataset', 1, TestDataset.RecordCount);
+  TestDataset.Close;
+end;
+
+procedure Ttestsdfspecific.TestSingleLineNoHeader;
+// A file with a single data line, no header should return 1 records
+const
+  InputFilename='single.csv';
+var
+  FileStrings: TStringList;
+begin
+  TestDataSet.Close;
+
+  if FileExists(InputFilename) then DeleteFile(InputFilename);
+  FileStrings:=TStringList.Create;
+  try
+    FileStrings.Add('1,SimpleName,31-12-1976');
+    FileStrings.SaveToFile(InputFileName);
+  finally
+    FileStrings.Free;
+  end;
+
+  TestDataset.FileMustExist:=false;
+  TestDataset.FirstLineAsSchema := false;
+  TestDataset.FileName:=InputFilename;
+  TestDataset.Open;
+
+  TestDataset.Last;
+  TestDataset.First;
+  AssertEquals('Number of records in test dataset', 1, TestDataset.RecordCount);
+  TestDataset.Close;
+end;
+
+procedure Ttestsdfspecific.TestOutput;
 const
 const
   OutputFilename='output.csv';
   OutputFilename='output.csv';
 begin
 begin
@@ -72,7 +173,7 @@ begin
   TestDataset.Close;
   TestDataset.Close;
 end;
 end;
 
 
-procedure Ttestexport1.TestInputOurFormat;
+procedure Ttestsdfspecific.TestInputOurFormat;
 // Test if input works with our format
 // Test if input works with our format
 // Mainly check if reading quotes is according to Delphi sdf specs and works.
 // Mainly check if reading quotes is according to Delphi sdf specs and works.
 // See test results from bug 19610 for evidence that the strings below should work.
 // See test results from bug 19610 for evidence that the strings below should work.
@@ -136,7 +237,7 @@ begin
   AssertEquals(Expected7, TestDataSet.FieldByName('NAME').AsString);
   AssertEquals(Expected7, TestDataSet.FieldByName('NAME').AsString);
 end;
 end;
 
 
-procedure Ttestexport1.TestDelimitedTextOutput;
+procedure Ttestsdfspecific.TestDelimitedTextOutput;
 // Test if input works with our format
 // Test if input works with our format
 // Mainly check if reading quotes is according to Delphi sdf specs and works.
 // Mainly check if reading quotes is according to Delphi sdf specs and works.
 // See test results from bug 19610 for evidence that the strings below should work.
 // See test results from bug 19610 for evidence that the strings below should work.
@@ -193,7 +294,7 @@ begin
 end;
 end;
 
 
 
 
-procedure Ttestexport1.Setup;
+procedure Ttestsdfspecific.Setup;
 
 
 begin
 begin
   TestDataset := TSDFDataset.Create(nil);
   TestDataset := TSDFDataset.Create(nil);
@@ -205,7 +306,7 @@ begin
   TestDataset.Schema.Add('BIRTHDAY');
   TestDataset.Schema.Add('BIRTHDAY');
 end;
 end;
 
 
-procedure Ttestexport1.Teardown;
+procedure Ttestsdfspecific.Teardown;
 begin
 begin
   try
   try
     TestDataset.Close;
     TestDataset.Close;
@@ -222,7 +323,12 @@ begin
 end;
 end;
 
 
 initialization
 initialization
-
-  Registertest(Ttestexport1);
+  // Only run these tests if we are running
+  // sdf tests. After all, running these when testing
+  // e.g. SQL RDBMS doesn't make sense.
+  if uppercase(dbconnectorname)='SDFDS' then
+    begin
+    Registertest(Ttestsdfspecific);
+    end;
 end.
 end.
 
 

+ 2 - 2
packages/fcl-db/tests/toolsunit.pas

@@ -330,11 +330,11 @@ begin
       testValues[ftDateTime,i] := testDateValues[i];
       testValues[ftDateTime,i] := testDateValues[i];
     end;
     end;
 
 
-  if dbconnectorname = '' then raise Exception.Create('There is no db-connector specified');
+  if dbconnectorname = '' then raise Exception.Create('There is no db connector specified');
   DBConnectorClass := GetClass('T'+dbconnectorname+'DBConnector');
   DBConnectorClass := GetClass('T'+dbconnectorname+'DBConnector');
   if assigned(DBConnectorClass) then
   if assigned(DBConnectorClass) then
     DBConnector := TDBConnectorClass(DBConnectorClass).create
     DBConnector := TDBConnectorClass(DBConnectorClass).create
-  else Raise Exception.Create('Unknown db-connector specified: ' + 'T'+dbconnectorname+'DBConnector');
+  else Raise Exception.Create('Unknown db connector specified: ' + 'T'+dbconnectorname+'DBConnector');
   inc(DBConnectorRefCount);
   inc(DBConnectorRefCount);
 end;
 end;