fpspreadsheet: Add more conditional formatting unit tests covering all conditions.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7532 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2020-07-09 11:04:37 +00:00
parent b4154727a1
commit e14818039f
2 changed files with 184 additions and 30 deletions

View File

@@ -1267,17 +1267,13 @@ end;
procedure TsSpreadOOXMLReader.ReadCFAverage(ANode: TDOMNode; procedure TsSpreadOOXMLReader.ReadCFAverage(ANode: TDOMNode;
AWorksheet: TsBasicWorksheet; ARange: TsCellRange; AFormatIndex: Integer); AWorksheet: TsBasicWorksheet; ARange: TsCellRange; AFormatIndex: Integer);
var var
s, sEquAve, sAboveAve: String; s, sStdDev, sEquAve, sAboveAve: String;
condition: TsCFCondition; condition: TsCFCondition;
stdDev: Double; stdDev: Double;
sheet: TsWorksheet; sheet: TsWorksheet;
begin begin
sheet := TsWorksheet(AWorksheet); sheet := TsWorksheet(AWorksheet);
s := GetAttrValue(ANode, 'stdDev');
if not TryStrToFloat(s, stdDev, FPointSeparatorSettings) then
stdDev := 0.0;
sEquAve := GetAttrValue(ANode, 'equalAverage'); sEquAve := GetAttrValue(ANode, 'equalAverage');
sAboveAve := GetAttrValue(ANode, 'aboveAverage'); sAboveAve := GetAttrValue(ANode, 'aboveAverage');
@@ -1295,7 +1291,14 @@ begin
condition := cfcAboveAverage; condition := cfcAboveAverage;
end; end;
sheet.WriteConditionalCellFormat(ARange, condition, stdDev, AFormatIndex); sStdDev := GetAttrValue(ANode, 'stdDev');
if not TryStrToFloat(sStdDev, stdDev, FPointSeparatorSettings) then
sStdDev := ''; // This will omit the "stdDev" attribute
if sStdDev = '' then
sheet.WriteConditionalCellFormat(ARange, condition, AFormatIndex)
else
sheet.WriteConditionalCellFormat(ARange, condition, stdDev, AFormatIndex);
end; end;
@@ -1526,7 +1529,7 @@ begin
if not found then if not found then
exit; exit;
if condition in [cfcAboveAverage..cfcBottomPercent] then if condition in [cfcBeginsWith..cfcNotContainsText] then
begin begin
s := GetAttrValue(ANode, 'text'); s := GetAttrValue(ANode, 'text');
sheet. WriteConditionalCellFormat(ARange, condition, s, AFormatIndex); sheet. WriteConditionalCellFormat(ARange, condition, s, AFormatIndex);
@@ -1848,7 +1851,7 @@ begin
ReadCFAverage(childNode, AWorksheet, range, fmtIdx); ReadCFAverage(childNode, AWorksheet, range, fmtIdx);
'top10': 'top10':
ReadCFTop10(childNode, AWorksheet, range, fmtIdx); ReadCFTop10(childNode, AWorksheet, range, fmtIdx);
'unique', 'duplicate', 'containsErrors', 'notContainsErrors': 'uniqueValues', 'duplicateValues', 'containsErrors', 'notContainsErrors':
ReadCFMisc(childNode, AWorksheet, range, fmtIdx); ReadCFMisc(childNode, AWorksheet, range, fmtIdx);
'containsText', 'notContainsText', 'beginsWith', 'endsWith': 'containsText', 'notContainsText', 'beginsWith', 'endsWith':
ReadCFMisc(childNode, AWorksheet, range, fmtIdx); ReadCFMisc(childNode, AWorksheet, range, fmtIdx);
@@ -4089,8 +4092,8 @@ begin
param1Str := ' aboveAverage="0"'; param1Str := ' aboveAverage="0"';
if (ARule.Condition in [cfcAboveEqualAverage, cfcBelowEqualAverage]) then if (ARule.Condition in [cfcAboveEqualAverage, cfcBelowEqualAverage]) then
param2Str := ' equalAverage="1"'; param2Str := ' equalAverage="1"';
if not ((ARule.Operand1 = varNull) or (ARule.Operand1 = 0)) then if VarIsNumeric(ARule.Operand1) or (ARule.Operand1 = 0) then
param3Str := Format(' stdDev="%d"', [ARule.Operand1]); param3Str := Format(' stdDev="%g"', [double(ARule.Operand1)]);
end; end;
cfcTop, cfcBottom, cfcTopPercent, cfcBottomPercent: cfcTop, cfcBottom, cfcTopPercent, cfcBottomPercent:
begin begin

View File

@@ -13,6 +13,7 @@ uses
// Not using Lazarus package as the user may be working with multiple versions // Not using Lazarus package as the user may be working with multiple versions
// Instead, add .. to unit search path // Instead, add .. to unit search path
Classes, SysUtils, fpcunit, testutils, testregistry, testsutility, Classes, SysUtils, fpcunit, testutils, testregistry, testsutility,
Math, Variants,
fpsTypes, fpsUtils, fpsAllFormats, fpSpreadsheet, fpsConditionalFormat; fpsTypes, fpsUtils, fpsAllFormats, fpSpreadsheet, fpsConditionalFormat;
type type
@@ -27,7 +28,11 @@ type
// Test conditional cell format // Test conditional cell format
procedure TestWriteRead_CF_Number(AFormat: TsSpreadsheetFormat; procedure TestWriteRead_CF_Number(AFormat: TsSpreadsheetFormat;
ACondition: TsCFCondition; AValue1: Integer = MaxInt; AValue2: Integer = MaxInt); ACondition: TsCFCondition; AValue1, AValue2: Variant);
procedure TestWriteRead_CF_Number(AFormat: TsSpreadsheetFormat;
ACondition: TsCFCondition; AValue1: Variant);
procedure TestWriteRead_CF_Number(AFormat: TsSpreadsheetFormat;
ACondition: TsCFCondition);
published published
procedure TestWriteRead_CF_Number_XLSX_Equal_Const; procedure TestWriteRead_CF_Number_XLSX_Equal_Const;
@@ -38,12 +43,30 @@ type
procedure TestWriteRead_CF_Number_XLSX_LessEqual_Const; procedure TestWriteRead_CF_Number_XLSX_LessEqual_Const;
procedure TestWriteRead_CF_Number_XLSX_Between_Const; procedure TestWriteRead_CF_Number_XLSX_Between_Const;
procedure TestWriteRead_CF_Number_XLSX_NotBetween_Const; procedure TestWriteRead_CF_Number_XLSX_NotBetween_Const;
procedure TestWriteRead_CF_Number_XLSX_AboveAverage;
procedure TestWriteRead_CF_Number_XLSX_BelowAverage;
procedure TestWriteRead_CF_Number_XLSX_AboveEqualAverage;
procedure TestWriteRead_CF_Number_XLSX_BelowEqualAverage;
procedure TestWriteRead_CF_Number_XLSX_AboveAverage_2StdDev;
procedure TestWriteRead_CF_Number_XLSX_BelowAverage_2StdDev;
procedure TestWriteRead_CF_NUMBER_XLSX_Top3;
procedure TestWriteRead_CF_NUMBER_XLSX_Top10Percent;
procedure TestWriteRead_CF_NUMBER_XLSX_Bottom3;
procedure TestWriteRead_CF_NUMBER_XLSX_Bottom10Percent;
procedure TestWriteRead_CF_NUMBER_XLSX_BeginsWith;
procedure TestWriteRead_CF_NUMBER_XLSX_EndsWith;
procedure TestWriteRead_CF_NUMBER_XLSX_Contains;
procedure TestWriteRead_CF_NUMBER_XLSX_NotContains;
procedure TestWriteRead_CF_NUMBER_XLSX_Unique;
procedure TestWriteRead_CF_NUMBER_XLSX_Duplicate;
procedure TestWriteRead_CF_Number_XLSX_ContainsErrors;
procedure TestWriteRead_CF_Number_XLSX_NotContainsErrors;
end; end;
implementation implementation
uses uses
Math, TypInfo; TypInfo;
{ TSpreadWriteReadCFTests } { TSpreadWriteReadCFTests }
@@ -61,9 +84,31 @@ end;
{ CFCellFormat tests. Detected cells get a red background. } { CFCellFormat tests. Detected cells get a red background. }
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_Number(
AFormat: TsSpreadsheetFormat; ACondition: TsCFCondition);
var
dummy: variant;
begin
VarClear(dummy);
TestWriteRead_CF_NUMBER(AFormat, ACondition, dummy, dummy);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_Number( procedure TSpreadWriteReadCFTests.TestWriteRead_CF_Number(
AFormat: TsSpreadsheetFormat; ACondition: TsCFCondition; AFormat: TsSpreadsheetFormat; ACondition: TsCFCondition;
AValue1: Integer = MaxInt; AValue2: Integer = MaxInt); AValue1: Variant);
var
dummy: Variant;
begin
VarClear(dummy);
TestWriteRead_CF_NUMBER(AFormat, ACondition, AValue1, dummy);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_Number(
AFormat: TsSpreadsheetFormat; ACondition: TsCFCondition;
AValue1, AValue2: Variant);
const
SHEET_NAME = 'CF';
TEXTS: array[0..6] of String = ('abc', 'def', 'ghi', 'abc', 'jkl', 'akl', 'ab');
var var
worksheet: TsWorksheet; worksheet: TsWorksheet;
workbook: TsWorkbook; workbook: TsWorkbook;
@@ -82,12 +127,17 @@ begin
// Write out all test values // Write out all test values
workbook := TsWorkbook.Create; workbook := TsWorkbook.Create;
try try
workSheet:= workBook.AddWorksheet('CF'); workbook.Options := [boAutoCalc];
workSheet:= workBook.AddWorksheet(SHEET_NAME);
// Write test data: two rows with numbers 1..10 row := 0;
for Row := 0 to 1 do for Col := 0 to High(TEXTS) do
for Col := 0 to 9 do worksheet.WriteText(row, col, TEXTS[col]);
worksheet.WriteNumber(row, col, col+1);
row := 1;
for col := 0 to 9 do
worksheet.WriteNumber(row, col, col+1);
worksheet.WriteFormula(row, col, '=1/0');
// Write format used by the cells detected by conditional formatting // Write format used by the cells detected by conditional formatting
InitFormatRecord(sollFmt); InitFormatRecord(sollFmt);
@@ -95,11 +145,11 @@ begin
sollFmtIdx := workbook.AddCellFormat(sollFmt); sollFmtIdx := workbook.AddCellFormat(sollFmt);
// Write instruction for conditional formatting // Write instruction for conditional formatting
sollRange := Range(0, 0, 0, 8); sollRange := Range(0, 0, 1, 10);
if (AValue1 = MaxInt) and (AValue2 = MaxInt) then if VarIsEmpty(AValue1) and VarIsEmpty(AValue2) then
worksheet.WriteConditionalCellFormat(sollRange, ACondition, sollFmtIdx) worksheet.WriteConditionalCellFormat(sollRange, ACondition, sollFmtIdx)
else else
if (AValue2 = MaxInt) then if VarIsEmpty(AValue2) then
worksheet.WriteConditionalCellFormat(sollRange, ACondition, AValue1, sollFmtIdx) worksheet.WriteConditionalCellFormat(sollRange, ACondition, AValue1, sollFmtIdx)
else else
worksheet.WriteConditionalCellFormat(sollRange, ACondition, AValue1, AValue2, sollFmtIdx); worksheet.WriteConditionalCellFormat(sollRange, ACondition, AValue1, AValue2, sollFmtIdx);
@@ -115,7 +165,7 @@ begin
workbook := TsWorkbook.Create; workbook := TsWorkbook.Create;
try try
workbook.ReadFromFile(TempFile, AFormat); workbook.ReadFromFile(TempFile, AFormat);
worksheet := GetWorksheetByName(workBook, 'CF'); worksheet := GetWorksheetByName(workBook, SHEET_NAME);
if worksheet=nil then if worksheet=nil then
fail('Error in test code. Failed to get named worksheet'); fail('Error in test code. Failed to get named worksheet');
@@ -149,20 +199,31 @@ begin
// Check 1st parameter // Check 1st parameter
actValue1 := TsCFCellRule(cf.Rules[0]).Operand1; actValue1 := TsCFCellRule(cf.Rules[0]).Operand1;
if AValue1 <> MaxInt then if not VarIsEmpty(AValue1) then
CheckEquals(AValue1, Integer(actValue1), 'Conditional format parameter 1 mismatch') begin
else if VarIsStr(AValue1) then
CheckEquals(Integer(varEmpty), Integer(actValue1), 'Omitted parameter 1 detected.'); CheckEquals(VarToStr(AValue1), VarToStr(actValue1), 'Conditional format parameter 1 mismatch')
else if VarIsNumeric(AValue1) then
CheckEquals(Double(AValue1), Double(actValue1), 'Conditional format parameter 1 mismatch')
else
raise Exception.Create('Unknown data type in variant');
end else
CheckEquals(true, VarIsEmpty(actValue1), 'Omitted parameter 1 detected.');
// Check 2nd parameter // Check 2nd parameter
actValue2 := TsCFCellRule(cf.Rules[0]).Operand2; actValue2 := TsCFCellRule(cf.Rules[0]).Operand2;
if AValue2 <> MaxInt then if not (VarIsEmpty(AValue2) or VarIsNull(AValue2)) then
CheckEquals(AValue2, actValue2, 'Conditional format parameter 2 mismatch') begin
else if VarIsStr(AValue2) then
CheckEquals(Integer(varEmpty), Integer(actValue2), 'Omitted parameter 2 detected.'); CheckEquals(VarToStr(AValue2), VarToStr(actValue2), 'Conditional format parameter 2 mismatch')
else
CheckEquals(Double(AValue2), Double(actValue2), 'Conditional format parameter 2 mismatch');
end else
CheckEquals(true, VarIsEmpty(actValue2), 'Omitted parameter 2 detected.');
finally finally
workbook.Free; workbook.Free;
DeleteFile(tempFile);
end; end;
end; end;
@@ -206,6 +267,96 @@ begin
TestWriteRead_CF_Number(sfOOXML, cfcNotBetween, 3, 7); TestWriteRead_CF_Number(sfOOXML, cfcNotBetween, 3, 7);
end; end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_Number_XLSX_AboveAverage;
begin
TestWriteRead_CF_Number(sfOOXML, cfcAboveAverage);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_Number_XLSX_BelowAverage;
begin
TestWriteRead_CF_Number(sfOOXML, cfcBelowAverage);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_Number_XLSX_AboveEqualAverage;
begin
TestWriteRead_CF_Number(sfOOXML, cfcAboveEqualAverage);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_Number_XLSX_BelowEqualAverage;
begin
TestWriteRead_CF_Number(sfOOXML, cfcBelowEqualAverage);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_Number_XLSX_AboveAverage_2StdDev;
begin
TestWriteRead_CF_Number(sfOOXML, cfcAboveAverage, 2.0);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_Number_XLSX_BelowAverage_2StdDev;
begin
TestWriteRead_CF_Number(sfOOXML, cfcBelowAverage, 2.0);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_NUMBER_XLSX_Top3;
begin
TestWriteRead_CF_Number(sfOOXML, cfcTop, 3);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_NUMBER_XLSX_Top10Percent;
begin
TestWriteRead_CF_Number(sfOOXML, cfcTopPercent, 10);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_NUMBER_XLSX_Bottom3;
begin
TestWriteRead_CF_Number(sfOOXML, cfcBottom, 3);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_NUMBER_XLSX_Bottom10Percent;
begin
TestWriteRead_CF_Number(sfOOXML, cfcBottomPercent, 10);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_NUMBER_XLSX_BeginsWith;
begin
TestWriteRead_CF_Number(sfOOXML, cfcBeginsWith, 'ab');
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_NUMBER_XLSX_EndsWith;
begin
TestWriteRead_CF_Number(sfOOXML, cfcEndsWith, 'kl');
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_NUMBER_XLSX_Contains;
begin
TestWriteRead_CF_Number(sfOOXML, cfcEndsWith, 'b');
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_NUMBER_XLSX_NotContains;
begin
TestWriteRead_CF_Number(sfOOXML, cfcEndsWith, 'b');
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_NUMBER_XLSX_Unique;
begin
TestWriteRead_CF_Number(sfOOXML, cfcUnique);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_NUMBER_XLSX_Duplicate;
begin
TestWriteRead_CF_Number(sfOOXML, cfcDuplicate);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_Number_XLSX_ContainsErrors;
begin
TestWriteRead_CF_Number(sfOOXML, cfcContainsErrors);
end;
procedure TSpreadWriteReadCFTests.TestWriteRead_CF_Number_XLSX_NotContainsErrors;
begin
TestWriteRead_CF_Number(sfOOXML, cfcNotContainsErrors);
end;
initialization initialization
RegisterTest(TSpreadWriteReadCFTests); RegisterTest(TSpreadWriteReadCFTests);