2014-05-24 20:28:05 +00:00
|
|
|
unit formulatests;
|
|
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
|
2014-06-28 19:40:28 +00:00
|
|
|
{ Deactivate this define in order to bypass tests which will raise an exception
|
|
|
|
when the corresponding rpn formula is calculated. }
|
|
|
|
{.$DEFINE ENABLE_CALC_RPN_EXCEPTIONS}
|
|
|
|
|
2014-07-01 12:55:02 +00:00
|
|
|
{ Deactivate this define to include errors in the structure of the rpn formulas.
|
|
|
|
Note that Excel report a corrupted file when trying to read this file }
|
|
|
|
{.DEFINE ENABLE_DEFECTIVE_FORMULAS }
|
|
|
|
|
2014-06-28 19:40:28 +00:00
|
|
|
|
2014-05-24 20:28:05 +00:00
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
|
|
|
// Not using Lazarus package as the user may be working with multiple versions
|
|
|
|
// Instead, add .. to unit search path
|
|
|
|
Classes, SysUtils, fpcunit, testutils, testregistry,
|
2014-07-01 07:39:06 +00:00
|
|
|
fpsallformats, fpspreadsheet, fpsfunc,
|
2014-06-28 19:40:28 +00:00
|
|
|
xlsbiff8 {and a project requirement for lclbase for utf8 handling},
|
2014-05-24 20:28:05 +00:00
|
|
|
testsutility;
|
|
|
|
|
|
|
|
type
|
|
|
|
{ TSpreadWriteReadFormula }
|
|
|
|
//Write to xls/xml file and read back
|
|
|
|
TSpreadWriteReadFormulaTests = class(TTestCase)
|
|
|
|
private
|
|
|
|
protected
|
|
|
|
// Set up expected values:
|
|
|
|
procedure SetUp; override;
|
|
|
|
procedure TearDown; override;
|
|
|
|
// Test formula strings
|
|
|
|
procedure TestWriteReadFormulaStrings(AFormat: TsSpreadsheetFormat);
|
2014-06-28 19:40:28 +00:00
|
|
|
// Test calculation of rpn formulas
|
|
|
|
procedure TestCalcRPNFormulas(AFormat: TsSpreadsheetformat);
|
2014-05-24 20:28:05 +00:00
|
|
|
|
|
|
|
published
|
|
|
|
// Writes out numbers & reads back.
|
|
|
|
// If previous read tests are ok, this effectively tests writing.
|
2014-05-25 16:49:45 +00:00
|
|
|
{ BIFF2 Tests }
|
2014-06-06 12:17:45 +00:00
|
|
|
procedure TestWriteRead_BIFF2_FormulaStrings;
|
2014-05-25 16:49:45 +00:00
|
|
|
{ BIFF5 Tests }
|
2014-06-06 12:17:45 +00:00
|
|
|
procedure TestWriteRead_BIFF5_FormulaStrings;
|
2014-05-24 20:28:05 +00:00
|
|
|
{ BIFF8 Tests }
|
2014-06-06 12:17:45 +00:00
|
|
|
procedure TestWriteRead_BIFF8_FormulaStrings;
|
2014-06-28 19:40:28 +00:00
|
|
|
|
|
|
|
// Writes out and calculates formulas, read back
|
2014-07-01 22:47:10 +00:00
|
|
|
{ BIFF2 Tests }
|
|
|
|
procedure TestWriteRead_BIFF2_CalcRPNFormula;
|
|
|
|
{ BIFF5 Tests }
|
|
|
|
procedure TestWriteRead_BIFF5_CalcRPNFormula;
|
2014-06-28 19:40:28 +00:00
|
|
|
{ BIFF8 Tests }
|
|
|
|
procedure TestWriteRead_BIFF8_CalcRPNFormula;
|
2014-05-24 20:28:05 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
2014-06-30 22:30:23 +00:00
|
|
|
math, typinfo, lazUTF8, fpsUtils, rpnFormulaUnit;
|
2014-05-24 20:28:05 +00:00
|
|
|
|
|
|
|
{ TSpreadWriteReadFormatTests }
|
|
|
|
|
|
|
|
procedure TSpreadWriteReadFormulaTests.SetUp;
|
|
|
|
begin
|
|
|
|
inherited SetUp;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TSpreadWriteReadFormulaTests.TearDown;
|
|
|
|
begin
|
|
|
|
inherited TearDown;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TSpreadWriteReadFormulaTests.TestWriteReadFormulaStrings(AFormat: TsSpreadsheetFormat);
|
|
|
|
const
|
|
|
|
SHEET = 'Sheet1';
|
|
|
|
var
|
|
|
|
MyWorksheet: TsWorksheet;
|
|
|
|
MyWorkbook: TsWorkbook;
|
2014-06-19 19:25:40 +00:00
|
|
|
Row: Integer;
|
2014-05-24 20:28:05 +00:00
|
|
|
TempFile: string; //write xls/xml to this file and read back from it
|
|
|
|
expected: String;
|
|
|
|
actual: String;
|
|
|
|
cell: PCell;
|
|
|
|
begin
|
|
|
|
TempFile := GetTempFileName;
|
|
|
|
|
|
|
|
// Create test workbook
|
|
|
|
MyWorkbook := TsWorkbook.Create;
|
|
|
|
MyWorkSheet:= MyWorkBook.AddWorksheet(SHEET);
|
|
|
|
|
|
|
|
// Write out all test formulas
|
|
|
|
// All formulas are in column B
|
2014-05-25 16:49:45 +00:00
|
|
|
WriteRPNFormulaSamples(MyWorksheet, AFormat, true);
|
2014-05-24 20:28:05 +00:00
|
|
|
MyWorkBook.WriteToFile(TempFile, AFormat, true);
|
|
|
|
MyWorkbook.Free;
|
|
|
|
|
|
|
|
// Open the spreadsheet
|
|
|
|
MyWorkbook := TsWorkbook.Create;
|
2014-05-25 16:49:45 +00:00
|
|
|
MyWorkbook.ReadFormulas := true;
|
|
|
|
|
2014-05-24 20:28:05 +00:00
|
|
|
MyWorkbook.ReadFromFile(TempFile, AFormat);
|
|
|
|
if AFormat = sfExcel2 then
|
|
|
|
MyWorksheet := MyWorkbook.GetFirstWorksheet
|
|
|
|
else
|
|
|
|
MyWorksheet := GetWorksheetByName(MyWorkBook, SHEET);
|
|
|
|
if MyWorksheet=nil then
|
|
|
|
fail('Error in test code. Failed to get named worksheet');
|
2014-05-26 15:27:35 +00:00
|
|
|
for Row := 0 to MyWorksheet.GetLastRowIndex do begin
|
2014-05-24 20:28:05 +00:00
|
|
|
cell := MyWorksheet.FindCell(Row, 1);
|
|
|
|
if (cell <> nil) and (Length(cell^.RPNFormulaValue) > 0) then begin
|
|
|
|
actual := MyWorksheet.ReadRPNFormulaAsString(cell);
|
|
|
|
expected := MyWorksheet.ReadAsUTF8Text(Row, 0);
|
2014-05-25 16:49:45 +00:00
|
|
|
CheckEquals(expected, actual, 'Test read formula mismatch, cell '+CellNotation(MyWorkSheet,Row,1));
|
2014-05-24 20:28:05 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// Finalization
|
|
|
|
MyWorkbook.Free;
|
|
|
|
DeleteFile(TempFile);
|
|
|
|
end;
|
|
|
|
|
2014-06-06 12:17:45 +00:00
|
|
|
procedure TSpreadWriteReadFormulaTests.TestWriteRead_BIFF2_FormulaStrings;
|
2014-05-25 16:49:45 +00:00
|
|
|
begin
|
|
|
|
TestWriteReadFormulaStrings(sfExcel2);
|
|
|
|
end;
|
|
|
|
|
2014-06-06 12:17:45 +00:00
|
|
|
procedure TSpreadWriteReadFormulaTests.TestWriteRead_BIFF5_FormulaStrings;
|
2014-05-25 16:49:45 +00:00
|
|
|
begin
|
|
|
|
TestWriteReadFormulaStrings(sfExcel5);
|
|
|
|
end;
|
|
|
|
|
2014-06-06 12:17:45 +00:00
|
|
|
procedure TSpreadWriteReadFormulaTests.TestWriteRead_BIFF8_FormulaStrings;
|
2014-05-24 20:28:05 +00:00
|
|
|
begin
|
|
|
|
TestWriteReadFormulaStrings(sfExcel8);
|
|
|
|
end;
|
|
|
|
|
2014-06-28 19:40:28 +00:00
|
|
|
|
|
|
|
{ Test calculation of rpn formulas }
|
|
|
|
|
|
|
|
procedure TSpreadWriteReadFormulaTests.TestCalcRPNFormulas(AFormat: TsSpreadsheetFormat);
|
|
|
|
const
|
|
|
|
SHEET = 'Sheet1';
|
|
|
|
var
|
|
|
|
MyWorksheet: TsWorksheet;
|
|
|
|
MyWorkbook: TsWorkbook;
|
|
|
|
Row: Integer;
|
|
|
|
TempFile: string; //write xls/xml to this file and read back from it
|
|
|
|
actual: TsArgument;
|
|
|
|
expected: TsArgument;
|
|
|
|
cell: PCell;
|
|
|
|
sollValues: array of TsArgument;
|
2014-06-30 13:21:04 +00:00
|
|
|
formula: String;
|
2014-07-01 12:55:02 +00:00
|
|
|
s: String;
|
|
|
|
t: TTime;
|
|
|
|
hr,min,sec,msec: Word;
|
2014-06-28 19:40:28 +00:00
|
|
|
begin
|
|
|
|
TempFile := GetTempFileName;
|
|
|
|
|
|
|
|
// Create test workbook
|
|
|
|
MyWorkbook := TsWorkbook.Create;
|
|
|
|
MyWorkSheet:= MyWorkBook.AddWorksheet(SHEET);
|
|
|
|
MyWorkSheet.Options := MyWorkSheet.Options + [soCalcBeforeSaving];
|
|
|
|
// Calculation of rpn formulas must be activated expicitely!
|
|
|
|
|
|
|
|
{ Write out test formulas.
|
|
|
|
This include file creates various rpn formulas and stores the expected
|
|
|
|
results in array "sollValues".
|
|
|
|
The test file contains the text representation in column A, and the
|
|
|
|
formula in column B. }
|
|
|
|
Row := 0;
|
|
|
|
{$I testcases_calcrpnformula.inc}
|
|
|
|
|
|
|
|
MyWorkBook.WriteToFile(TempFile, AFormat, true);
|
|
|
|
MyWorkbook.Free;
|
|
|
|
|
|
|
|
// Open the workbook
|
|
|
|
MyWorkbook := TsWorkbook.Create;
|
|
|
|
MyWorkbook.ReadFromFile(TempFile, AFormat);
|
|
|
|
if AFormat = sfExcel2 then
|
|
|
|
MyWorksheet := MyWorkbook.GetFirstWorksheet
|
|
|
|
else
|
|
|
|
MyWorksheet := GetWorksheetByName(MyWorkBook, SHEET);
|
|
|
|
if MyWorksheet=nil then
|
|
|
|
fail('Error in test code. Failed to get named worksheet');
|
|
|
|
|
|
|
|
for Row := 0 to MyWorksheet.GetLastRowIndex do begin
|
2014-06-30 13:21:04 +00:00
|
|
|
formula := MyWorksheet.ReadAsUTF8Text(Row, 0);
|
2014-06-28 19:40:28 +00:00
|
|
|
cell := MyWorksheet.FindCell(Row, 1);
|
|
|
|
if (cell = nil) then
|
|
|
|
fail('Error in test code: Failed to get cell ' + CellNotation(MyWorksheet, Row, 1));
|
|
|
|
case cell^.ContentType of
|
2014-06-29 09:55:47 +00:00
|
|
|
cctBool : actual := CreateBool(cell^.BoolValue);
|
2014-06-28 19:40:28 +00:00
|
|
|
cctNumber : actual := CreateNumber(cell^.NumberValue);
|
|
|
|
cctError : actual := CreateError(cell^.ErrorValue);
|
|
|
|
cctUTF8String : actual := CreateString(cell^.UTF8StringValue);
|
|
|
|
else fail('ContentType not supported');
|
|
|
|
end;
|
|
|
|
expected := SollValues[row];
|
|
|
|
CheckEquals(ord(expected.ArgumentType), ord(actual.ArgumentType),
|
2014-06-30 13:21:04 +00:00
|
|
|
'Test read calculated formula data type mismatch, formula "' + formula +
|
|
|
|
'", cell '+CellNotation(MyWorkSheet,Row,1));
|
2014-06-28 19:40:28 +00:00
|
|
|
case actual.ArgumentType of
|
|
|
|
atBool:
|
|
|
|
CheckEquals(BoolToStr(expected.BoolValue), BoolToStr(actual.BoolValue),
|
2014-06-30 13:21:04 +00:00
|
|
|
'Test read calculated formula result mismatch, formula "' + formula +
|
|
|
|
'", cell '+CellNotation(MyWorkSheet,Row,1));
|
2014-06-28 19:40:28 +00:00
|
|
|
atNumber:
|
|
|
|
CheckEquals(expected.NumberValue, actual.NumberValue,
|
2014-06-30 13:21:04 +00:00
|
|
|
'Test read calculated formula result mismatch, formula "' + formula +
|
|
|
|
'", cell '+CellNotation(MyWorkSheet,Row,1));
|
2014-06-28 19:40:28 +00:00
|
|
|
atString:
|
|
|
|
CheckEquals(expected.StringValue, actual.StringValue,
|
2014-06-30 13:21:04 +00:00
|
|
|
'Test read calculated formula result mismatch, formula "' + formula +
|
|
|
|
'", cell '+CellNotation(MyWorkSheet,Row,1));
|
2014-06-28 19:40:28 +00:00
|
|
|
atError:
|
|
|
|
CheckEquals(
|
|
|
|
GetEnumName(TypeInfo(TsErrorValue), ord(expected.ErrorValue)),
|
|
|
|
GetEnumname(TypeInfo(TsErrorValue), ord(actual.ErrorValue)),
|
2014-06-30 13:21:04 +00:00
|
|
|
'Test read calculated formula error value mismatch, formula ' + formula +
|
|
|
|
', cell '+CellNotation(MyWorkSheet,Row,1));
|
2014-06-28 19:40:28 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// Finalization
|
|
|
|
MyWorkbook.Free;
|
|
|
|
DeleteFile(TempFile);
|
|
|
|
end;
|
|
|
|
|
2014-07-01 22:47:10 +00:00
|
|
|
procedure TSpreadWriteReadFormulaTests.TestWriteRead_BIFF2_CalcRPNFormula;
|
|
|
|
begin
|
|
|
|
TestCalcRPNFormulas(sfExcel2);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TSpreadWriteReadFormulaTests.TestWriteRead_BIFF5_CalcRPNFormula;
|
|
|
|
begin
|
|
|
|
TestCalcRPNFormulas(sfExcel5);
|
|
|
|
end;
|
2014-06-28 19:40:28 +00:00
|
|
|
|
|
|
|
procedure TSpreadWriteReadFormulaTests.TestWriteRead_BIFF8_CalcRPNFormula;
|
|
|
|
begin
|
|
|
|
TestCalcRPNFormulas(sfExcel8);
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2014-05-24 20:28:05 +00:00
|
|
|
initialization
|
|
|
|
// Register so these tests are included in a full run
|
|
|
|
RegisterTest(TSpreadWriteReadFormulaTests);
|
|
|
|
|
|
|
|
|
|
|
|
end.
|
|
|
|
|