You've already forked lazarus-ccr
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:
@@ -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,6 +1291,13 @@ begin
|
|||||||
condition := cfcAboveAverage;
|
condition := cfcAboveAverage;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
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);
|
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
|
||||||
|
@@ -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]);
|
||||||
|
|
||||||
|
row := 1;
|
||||||
|
for col := 0 to 9 do
|
||||||
worksheet.WriteNumber(row, col, col+1);
|
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
|
||||||
|
if VarIsStr(AValue1) then
|
||||||
|
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
|
else
|
||||||
CheckEquals(Integer(varEmpty), Integer(actValue1), 'Omitted parameter 1 detected.');
|
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
|
||||||
|
if VarIsStr(AValue2) then
|
||||||
|
CheckEquals(VarToStr(AValue2), VarToStr(actValue2), 'Conditional format parameter 2 mismatch')
|
||||||
else
|
else
|
||||||
CheckEquals(Integer(varEmpty), Integer(actValue2), 'Omitted parameter 2 detected.');
|
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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user