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.
 
 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.
 Simply add the test* units in this directory to the uses statement of the
 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
 included in this directory.
 
+DBTestframework architecture
+============================
 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 
 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.
 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'
 configuration file. Also some settings which are connector-dependent can be set
 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), 
-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, 
 ; i.e. which database you want to use
 [Database]
-type=interbase
+type=bufdataset
 
 
 ; These sections are for the several SQLDB-types of databases:
@@ -117,3 +117,9 @@ connector=memds
 ; BufDataset in memory dataset:
 [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,
   DigestTestReport,
   toolsunit,
-// List of supported database-connectors
+// List of supported database connectors
   sqldbtoolsunit,
   dbftoolsunit,
   bufdatasettoolsunit,
   memdstoolsunit,
   SdfDSToolsUnit,
   tcsdfdata,
-// Units wich contains the tests
+// Units wich contain the tests
   TestBasics,
   TestFieldTypes,
   TestDatasources,

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

@@ -7,7 +7,6 @@
       <MainUnit Value="0"/>
       <ResourceType Value="res"/>
       <UseXPManifest Value="True"/>
-      <Icon Value="0"/>
     </General>
     <i18n>
       <EnableI18N LFM="False"/>
@@ -15,8 +14,23 @@
     <VersionInfo>
       <StringTable ProductVersion=""/>
     </VersionInfo>
-    <BuildModes Count="1">
+    <BuildModes Count="2">
       <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>
     <PublishOptions>
       <Version Value="2"/>
@@ -53,6 +67,11 @@
       <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>
+    <Linking>
+      <Debugging>
+        <GenerateDebugInfo Value="False"/>
+      </Debugging>
+    </Linking>
     <Other>
       <CompilerMessages>
         <UseMsgFile Value="True"/>

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

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

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

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

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

@@ -1,24 +1,28 @@
 unit tcsdfdata;
-// Tests multiline functionality of sdfdataset
+// Tests specific functionality of sdfdataset (multiline etc)
 
 {$mode objfpc}{$H+}
 
 interface
 
 uses
-  Classes, SysUtils, Fpcunit, Testutils, Testregistry,
-  dateutils, sdfdata;
+  Classes, SysUtils, Fpcunit, Testutils, Testregistry, testdecorator,
+  dateutils,sdfdata,ToolsUnit;
 
 type
 
-  { Ttestexport1 }
+  { Ttestsdfspecific }
 
-  Ttestexport1 = class(Ttestcase)
+  Ttestsdfspecific = class(Ttestcase)
   protected
     TestDataset: TSDFDataset;
     procedure Setup; override;
     procedure Teardown; override;
   published
+    procedure TestEmptyFileHeader;
+    procedure TestEmptyFileNoHeader;
+    procedure TestSingleLineHeader;
+    procedure TestSingleLineNoHeader;
     procedure TestOutput;
     procedure TestInputOurFormat;
     procedure TestDelimitedTextOutput;
@@ -26,7 +30,104 @@ type
 
 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
   OutputFilename='output.csv';
 begin
@@ -72,7 +173,7 @@ begin
   TestDataset.Close;
 end;
 
-procedure Ttestexport1.TestInputOurFormat;
+procedure Ttestsdfspecific.TestInputOurFormat;
 // Test if input works with our format
 // 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.
@@ -136,7 +237,7 @@ begin
   AssertEquals(Expected7, TestDataSet.FieldByName('NAME').AsString);
 end;
 
-procedure Ttestexport1.TestDelimitedTextOutput;
+procedure Ttestsdfspecific.TestDelimitedTextOutput;
 // Test if input works with our format
 // 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.
@@ -193,7 +294,7 @@ begin
 end;
 
 
-procedure Ttestexport1.Setup;
+procedure Ttestsdfspecific.Setup;
 
 begin
   TestDataset := TSDFDataset.Create(nil);
@@ -205,7 +306,7 @@ begin
   TestDataset.Schema.Add('BIRTHDAY');
 end;
 
-procedure Ttestexport1.Teardown;
+procedure Ttestsdfspecific.Teardown;
 begin
   try
     TestDataset.Close;
@@ -222,7 +323,12 @@ begin
 end;
 
 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.
 

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

@@ -330,11 +330,11 @@ begin
       testValues[ftDateTime,i] := testDateValues[i];
     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');
   if assigned(DBConnectorClass) then
     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);
 end;