You've already forked lazarus-ccr
fpspreadsheet: Add test case for switched decimal and thousand separators in csv file. Fix bugs related to that.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3674 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -561,7 +561,7 @@ begin
|
||||
if CSVParams.NumberFormat <> '' then
|
||||
s := Format(CSVParams.NumberFormat, [AValue], CSVParams.FormatSettings)
|
||||
else
|
||||
s := FWorksheet.ReadAsUTF8Text(ACell);
|
||||
s := FWorksheet.ReadAsUTF8Text(ACell, CSVParams.FormatSettings);
|
||||
AppendToStream(AStream, s);
|
||||
end;
|
||||
|
||||
|
@ -523,6 +523,7 @@ type
|
||||
{ Reading of values }
|
||||
function ReadAsUTF8Text(ARow, ACol: Cardinal): ansistring; overload;
|
||||
function ReadAsUTF8Text(ACell: PCell): ansistring; overload;
|
||||
function ReadAsUTF8Text(ACell: PCell; AFormatSettings: TFormatSettings): ansistring; overload;
|
||||
function ReadAsNumber(ARow, ACol: Cardinal): Double; overload;
|
||||
function ReadAsNumber(ACell: PCell): Double; overload;
|
||||
function ReadAsDateTime(ARow, ACol: Cardinal; out AResult: TDateTime): Boolean; overload;
|
||||
@ -2384,23 +2385,26 @@ end;
|
||||
@return The text representation of the cell
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsWorksheet.ReadAsUTF8Text(ACell: PCell): ansistring;
|
||||
begin
|
||||
Result := ReadAsUTF8Text(ACell, FWorkbook.FormatSettings);
|
||||
end;
|
||||
|
||||
function FloatToStrNoNaN(const Value: Double;
|
||||
function TsWorksheet.ReadAsUTF8Text(ACell: PCell;
|
||||
AFormatSettings: TFormatSettings): ansistring;
|
||||
|
||||
function FloatToStrNoNaN(const AValue: Double;
|
||||
ANumberFormat: TsNumberFormat; ANumberFormatStr: string): ansistring;
|
||||
var
|
||||
fs: TFormatSettings;
|
||||
begin
|
||||
fs := FWorkbook.FormatSettings;
|
||||
if IsNan(Value) then
|
||||
if IsNan(AValue) then
|
||||
Result := ''
|
||||
else
|
||||
if (ANumberFormat = nfGeneral) or (ANumberFormatStr = '') then
|
||||
Result := FloatToStr(Value, fs)
|
||||
Result := FloatToStr(AValue, AFormatSettings)
|
||||
else
|
||||
if (ANumberFormat = nfPercentage) then
|
||||
Result := FormatFloat(ANumberFormatStr, Value*100, fs)
|
||||
Result := FormatFloat(ANumberFormatStr, AValue*100, AFormatSettings)
|
||||
else
|
||||
Result := FormatFloat(ANumberFormatStr, Value, fs)
|
||||
Result := FormatFloat(ANumberFormatStr, AValue, AFormatSettings)
|
||||
end;
|
||||
|
||||
function DateTimeToStrNoNaN(const Value: Double;
|
||||
@ -2414,15 +2418,15 @@ function TsWorksheet.ReadAsUTF8Text(ACell: PCell): ansistring;
|
||||
if (ANumberFormat = nfGeneral) then
|
||||
begin
|
||||
if frac(Value) = 0 then // date only
|
||||
ANumberFormatStr := Workbook.FormatSettings.ShortDateFormat
|
||||
ANumberFormatStr := AFormatSettings.ShortDateFormat
|
||||
else if trunc(Value) = 0 then // time only
|
||||
ANumberFormatStr := Workbook.FormatSettings.LongTimeFormat
|
||||
ANumberFormatStr := AFormatSettings.LongTimeFormat
|
||||
else
|
||||
ANumberFormatStr := 'cc'
|
||||
end else
|
||||
if ANumberFormatStr = '' then
|
||||
ANumberFormatStr := BuildDateTimeFormatString(ANumberFormat,
|
||||
Workbook.FormatSettings, ANumberFormatStr);
|
||||
AFormatSettings, ANumberFormatStr);
|
||||
|
||||
// Saw strange cases in ods where date/time formats contained pos/neg/zero parts.
|
||||
// Split to be on the safe side.
|
||||
|
@ -119,8 +119,6 @@ function SpecialDateTimeFormat(ACode: String;
|
||||
procedure SplitFormatString(const AFormatString: String; out APositivePart,
|
||||
ANegativePart, AZeroPart: String);
|
||||
|
||||
|
||||
|
||||
procedure MakeTimeIntervalMask(Src: String; var Dest: String);
|
||||
|
||||
// These two functions are copies of fpc trunk until they are available in stable fpc.
|
||||
@ -1558,10 +1556,11 @@ begin
|
||||
dec(i);
|
||||
while i >= 1 do
|
||||
begin
|
||||
if not (AText[i] in ['0'..'9', '+', '-']) then
|
||||
if not (AText[i] in ['0'..'9', '+', '-', '.', ',']) then
|
||||
exit;
|
||||
|
||||
// If we find the testSep character again it must be a thousand separator.
|
||||
// If we find the testSep character again it must be a thousand separator,
|
||||
// and there are no decimals.
|
||||
if (AText[i] = testSep) then
|
||||
begin
|
||||
// ... but only if there are 3 numerical digits in between
|
||||
@ -1573,8 +1572,8 @@ begin
|
||||
fs.DecimalSeparator := ','
|
||||
else
|
||||
fs.DecimalSeparator := '.';
|
||||
ADecimalSeparator := fs.DecimalSeparator;
|
||||
AThousandSeparator := fs.ThousandSeparator;
|
||||
ADecimalSeparator := #0; // this indicates that there are no decimals
|
||||
done := true;
|
||||
i := 0;
|
||||
end else
|
||||
|
@ -65,7 +65,8 @@ type
|
||||
// Test word wrapping
|
||||
procedure TestWriteRead_WordWrap(AFormat: TsSpreadsheetFormat);
|
||||
// Test number formats
|
||||
procedure TestWriteRead_NumberFormats(AFormat: TsSpreadsheetFormat);
|
||||
procedure TestWriteRead_NumberFormats(AFormat: TsSpreadsheetFormat;
|
||||
AVariant: Integer = 0);
|
||||
// Repeat with date/times
|
||||
procedure TestWriteRead_DateTimeFormats(AFormat: TsSpreadsheetFormat);
|
||||
// Test merged cells
|
||||
@ -137,13 +138,14 @@ type
|
||||
procedure TestWriteRead_OOXML_WordWrap;
|
||||
|
||||
{ CSV Tests }
|
||||
procedure TestWriteRead_CSV_NumberFormats;
|
||||
procedure TestWriteRead_CSV_NumberFormats_0;
|
||||
procedure TestWriteRead_CSV_NumberFormats_1;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
TypInfo, fpsutils;
|
||||
TypInfo, fpsutils, fpscsv;
|
||||
|
||||
const
|
||||
FmtNumbersSheet = 'NumbersFormat'; //let's distinguish it from the regular numbers sheet
|
||||
@ -165,14 +167,18 @@ var
|
||||
i: Integer;
|
||||
fs: TFormatSettings;
|
||||
myworkbook: TsWorkbook;
|
||||
ch: Char;
|
||||
begin
|
||||
// Set up norm - MUST match spreadsheet cells exactly
|
||||
|
||||
// The workbook uses a slightly modified copy of the DefaultFormatSettings
|
||||
// We create a copy here in order to better define the predicted strings.
|
||||
myWorkbook := TsWorkbook.Create;
|
||||
fs := MyWorkbook.FormatSettings;
|
||||
myWorkbook.Free;
|
||||
try
|
||||
fs := MyWorkbook.FormatSettings;
|
||||
finally
|
||||
myWorkbook.Free;
|
||||
end;
|
||||
|
||||
// Numbers
|
||||
SollNumbers[0] := 0.0;
|
||||
@ -299,21 +305,33 @@ end;
|
||||
|
||||
{ --- Number format tests --- }
|
||||
|
||||
procedure TSpreadWriteReadFormatTests.TestWriteRead_NumberFormats(AFormat: TsSpreadsheetFormat);
|
||||
procedure TSpreadWriteReadFormatTests.TestWriteRead_NumberFormats(AFormat: TsSpreadsheetFormat;
|
||||
AVariant: Integer = 0);
|
||||
var
|
||||
MyWorksheet: TsWorksheet;
|
||||
MyWorkbook: TsWorkbook;
|
||||
ActualString: String;
|
||||
ExpectedString: String;
|
||||
Row, Col: Integer;
|
||||
TempFile: string; //write xls/xml to this file and read back from it
|
||||
begin
|
||||
{// Not needed: use workbook.writetofile with overwrite=true
|
||||
if fileexists(TempFile) then
|
||||
DeleteFile(TempFile);
|
||||
}
|
||||
// Write out all test values
|
||||
MyWorkbook := TsWorkbook.Create;
|
||||
try
|
||||
if (AFormat = sfCSV) then
|
||||
begin
|
||||
case AVariant of
|
||||
0: begin
|
||||
CSVParams.FormatSettings.DecimalSeparator := MyWorkbook.FormatSettings.DecimalSeparator;
|
||||
CSVParams.FormatSettings.ThousandSeparator := MyWorkbook.FormatSettings.ThousandSeparator;
|
||||
end;
|
||||
1: begin // interchanged decimal and thousand separators
|
||||
CSVParams.FormatSettings.ThousandSeparator := MyWorkbook.FormatSettings.DecimalSeparator;
|
||||
CSVParams.FormatSettings.DecimalSeparator := MyWorkbook.FormatSettings.ThousandSeparator;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
MyWorkSheet:= MyWorkBook.AddWorksheet(FmtNumbersSheet);
|
||||
for Row := Low(SollNumbers) to High(SollNumbers) do
|
||||
for Col := ord(Low(SollNumberFormats)) to ord(High(SollNumberFormats)) do
|
||||
@ -343,17 +361,18 @@ begin
|
||||
for Col := Low(SollNumberFormats) to High(SollNumberFormats) do
|
||||
begin
|
||||
ActualString := MyWorkSheet.ReadAsUTF8Text(Row,Col);
|
||||
if (SollNumberStrings[Row,Col] <> ActualString) then
|
||||
ExpectedString := SollNumberStrings[Row, Col];
|
||||
if (ExpectedString <> ActualString) then
|
||||
begin
|
||||
if (AFormat = sfCSV) and (Row=5) and (Col=0) then
|
||||
// CSV has an insignificant difference of tiny numbers in
|
||||
// general format
|
||||
ignore('Ignoring insignificant saved string mismatch, cell ' +
|
||||
CellNotation(MyWorksheet,Row,Col) +
|
||||
', expected: <' + SollNumberStrings[Row,Col] +
|
||||
', expected: <' + ExpectedString +
|
||||
'> but was: <' + ActualString + '>')
|
||||
else
|
||||
CheckEquals(SollNumberStrings[Row,Col], ActualString,
|
||||
CheckEquals(ExpectedString, ActualString,
|
||||
'Test saved string mismatch, cell '+CellNotation(MyWorkSheet,Row,Col));
|
||||
end;
|
||||
end;
|
||||
@ -388,9 +407,14 @@ begin
|
||||
TestWriteRead_NumberFormats(sfOOXML);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadFormatTests.TestWriteRead_CSV_NumberFormats;
|
||||
procedure TSpreadWriteReadFormatTests.TestWriteRead_CSV_NumberFormats_0;
|
||||
begin
|
||||
TestWriteRead_NumberFormats(sfCSV);
|
||||
TestWriteRead_NumberFormats(sfCSV, 0);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteReadFormatTests.TestWriteRead_CSV_NumberFormats_1;
|
||||
begin
|
||||
TestWriteRead_NumberFormats(sfCSV, 1);
|
||||
end;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user