You've already forked lazarus-ccr
fpexif: Initial commit of units and tests
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6080 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
327
components/fpexif/tests/unittest/common/fetutils.pas
Normal file
327
components/fpexif/tests/unittest/common/fetutils.pas
Normal file
@ -0,0 +1,327 @@
|
||||
unit fetUtils;
|
||||
|
||||
{$IFDEF FPC}
|
||||
{$mode delphi} //objfpc}{$H+}
|
||||
{$ENDIF}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils,
|
||||
{$IFDEF FPC}
|
||||
fpcunit, testutils, testregistry;
|
||||
{$ELSE}
|
||||
TestFrameWork;
|
||||
{$ENDIF}
|
||||
|
||||
type
|
||||
TstUtils = class(TTestCase)
|
||||
published
|
||||
procedure TestCountChar;
|
||||
procedure TestFloatToRational;
|
||||
procedure TestInsertSpaces;
|
||||
procedure TestLookup;
|
||||
procedure TestSplit;
|
||||
procedure TestSplitGPS;
|
||||
procedure TestStrToGPS;
|
||||
procedure TestStrToRational;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
math,
|
||||
fpeGlobal, fpeUtils;
|
||||
|
||||
type
|
||||
TCountCharParam = record
|
||||
TestString: String;
|
||||
ch: Char;
|
||||
Count: Integer;
|
||||
end;
|
||||
|
||||
TInsertSpacesParam = record
|
||||
TestString: String;
|
||||
ResultString: String;
|
||||
end;
|
||||
|
||||
TFloatToRationalParam = record
|
||||
Value, Precision: Double;
|
||||
Num, Denom: Integer;
|
||||
Error: Integer; // 0:ok, 1: Num is wrong, 2: Denom is wrong
|
||||
end;
|
||||
|
||||
TLookupParam = record
|
||||
SearchForKey: Boolean;
|
||||
SearchStr: String;
|
||||
ResultStr: String;
|
||||
end;
|
||||
|
||||
TSplitGpsParam = record
|
||||
Value: Double;
|
||||
Degs: Double;
|
||||
Mins: Double;
|
||||
Secs: Double
|
||||
end;
|
||||
|
||||
TSplitParam = record
|
||||
Text: String;
|
||||
Sep: String;
|
||||
NumParts: Integer;
|
||||
Parts: Array[0..2] of string;
|
||||
end;
|
||||
|
||||
TStrToGpsParam = record
|
||||
Text: String;
|
||||
Degs: Double;
|
||||
Valid: Boolean;
|
||||
end;
|
||||
|
||||
TStrToRationalParam = record
|
||||
Value: String;
|
||||
Num, Denom: Integer;
|
||||
end;
|
||||
|
||||
const
|
||||
CountCharParams: array[0..5] of TCountCharParam = (
|
||||
(TestString:''; ch:'a'; Count:0),
|
||||
(TestString:'a'; ch:'a'; Count:1),
|
||||
(TestString:'aa'; ch:'a'; Count:2),
|
||||
(TestString:'b'; ch:'a'; Count:0),
|
||||
(TestString:'ab'; ch:'a'; Count:1),
|
||||
(TestString:'ba'; ch:'a'; Count:1)
|
||||
);
|
||||
|
||||
InsertSpacesParams: array[0..14] of TInsertSpacesParam = (
|
||||
(TestString: 'Artist'; ResultString: 'Artist'),
|
||||
(TestString: 'ShutterSpeed'; ResultString: 'Shutter Speed'),
|
||||
(TestString: 'ThumbnailXResolution'; ResultString: 'Thumbnail X Resolution'),
|
||||
(TestString: 'YCbCrPositioning'; ResultString: 'Y Cb Cr Positioning'),
|
||||
(TestString: 'ISO'; ResultString: 'ISO'),
|
||||
(TestString: 'GPSInfo'; ResultString: 'GPS Info'),
|
||||
(TestString: 'IPTC/NAA'; ResultString: 'IPTC/NAA'),
|
||||
(TestString: 'XPTitle'; ResultString: 'XP Title'),
|
||||
(TestString: 'PrintIM'; ResultString: 'Print IM'),
|
||||
(TestString: 'ResolutionX'; ResultString: 'Resolution X'),
|
||||
(TestString: 'XResolution'; ResultString: 'X Resolution'),
|
||||
(TestString: 'CCD ISO'; ResultString: 'CCD ISO'),
|
||||
(TestString: 'AE setting'; ResultString: 'AE setting'),
|
||||
(TestString: 'abc ABC'; ResultString: 'abc ABC'),
|
||||
(TestString: 'abc Abc'; ResultString: 'abc Abc')
|
||||
);
|
||||
|
||||
FloatToRationalParams: array[0..8] of TFloatToRationalParam = (
|
||||
(Value:0.0; Precision: 1E-6; Num:0; Denom:1; Error:0), // 0
|
||||
(Value:1.0; Precision: 1E-6; Num:1; Denom:1; Error:0), // 1
|
||||
(Value:0.5; Precision: 1E-6; Num:1; Denom:2; Error:0), // 2
|
||||
(Value:0.01; Precision: 1E-6; Num:1; Denom:100; Error:0), // 3
|
||||
(Value:0.333333333; Precision: 1E-6; Num:1; Denom:3; Error:0), // 4
|
||||
(value:1.166666667; Precision: 1E-6; Num:7; Denom:6; Error:0), // 5
|
||||
(Value:NaN; Precision: 1E-6; Num:1; Denom:0; Error:0), // 6
|
||||
(Value:0.3333; Precision: 1E-6; Num:1; Denom:3; Error:2), // 7
|
||||
(Value:0.1; Precision: 1E-6; Num:1; Denom:3; Error:2) // 8
|
||||
);
|
||||
|
||||
LkupTbl: String = '0:Zero,1:One,2:Two';
|
||||
LookupParams: array[0..8] of TLookupParam = (
|
||||
(SearchForKey:true; SearchStr:'0'; ResultStr:'Zero'),
|
||||
(SearchForKey:true; SearchStr:'1'; ResultStr:'One'),
|
||||
(SearchForKey:true; SearchStr:'2'; ResultStr:'Two'),
|
||||
(SearchForKey:true; SearchStr:'$2'; ResultStr:'Two'),
|
||||
(SearchForKey:true; SearchStr:'3'; ResultStr:'3'),
|
||||
(SearchForKey:false; SearchStr:'Zero'; ResultStr:'0'),
|
||||
(SearchForKey:false; SearchStr:'One'; ResultStr:'1'),
|
||||
(SearchForKey:false; SearchStr:'Two'; ResultStr:'2'),
|
||||
(SearchForKey:false; SearchStr:'Three'; ResultStr:'')
|
||||
);
|
||||
|
||||
SplitGpsParams: array[0..3] of TSplitGpsParam = (
|
||||
(Value:0.5; Degs: 0; Mins:30; Secs: 0),
|
||||
(Value:2.777777E-4; Degs: 0; Mins: 0; Secs: 1),
|
||||
(Value:50.2527777777777; Degs:50; Mins:15; Secs:10),
|
||||
(Value:50.2583333333333; Degs:50; Mins:15; Secs:30)
|
||||
);
|
||||
|
||||
SplitParams: array[0..3] of TSplitParam = (
|
||||
(Text:'One'; Sep: ';'; NumParts: 1; Parts:('One', '', '')),
|
||||
(Text:'One,Two'; Sep: ','; NumParts: 2; Parts:('One', 'Two', '')),
|
||||
(Text:'One, Two'; Sep: ', '; NumParts: 2; Parts:('One', 'Two', '')),
|
||||
(Text:'One'#0'Two'; Sep: #0; NumParts: 2; Parts:('One', 'Two', ''))
|
||||
);
|
||||
|
||||
// 1/3600 = 2.77777777777E-4, 1/60 = 0,01666666666666667
|
||||
StrToGpsParams: array[0..11] of TStrToGpsParam = (
|
||||
(Text:'0 deg 30'' 0"'; Degs: 0.5; Valid: true),
|
||||
(Text:'0 deg 0'' 1"'; Degs: 2.777777E-4; Valid: true),
|
||||
(Text:'50 deg 15'' 10"'; Degs: 50.2527777777777; Valid: true),
|
||||
(Text:'50 deg 15'' 30"'; Degs: 50.2583333333333; Valid: true),
|
||||
(Text:'50 deg 15.5'''; Degs: 50.2583333333333; Valid: true),
|
||||
(Text:'50 deg 60'' 30"'; Degs: NaN; Valid: false),
|
||||
(Text:'50 deg 15'' 70"'; Degs: NaN; Valid: false),
|
||||
(Text:'50.1° 15'' 70"'; Degs: NaN; Valid: false),
|
||||
(Text:'50 deg 15.3'' 50"'; Degs: NaN; Valid: false),
|
||||
(Text:'50 deg -15'' 50"'; Degs: NaN; Valid: false),
|
||||
(Text:'50 deg 15'' -50"'; Degs: NaN; Valid: false),
|
||||
(Text:'-50 deg 15'' 30"'; Degs: 50.2583333333333; Valid: true)
|
||||
);
|
||||
|
||||
StrToRationalParams: array[0..9] of TStrToRationalParam = (
|
||||
(Value:'0'; Num:0; Denom:1), // 0
|
||||
(Value:'1'; Num:1; Denom:1), // 1
|
||||
(Value:'1/2'; Num:1; Denom:2), // 2
|
||||
(Value:'1/ 2'; Num:1; Denom:2), // 3
|
||||
(Value:'1 /2'; Num:1; Denom:2), // 4
|
||||
(Value:'1 / 2'; Num:1; denom:2), // 5
|
||||
(Value:' 1/2'; Num:1; Denom:2), // 6
|
||||
(Value:'1/2 '; Num:1; Denom:2), // 7
|
||||
(Value:' 1/2 '; Num:1; Denom:2), // 8
|
||||
(value:''; Num:1; Denom:0) // 9
|
||||
);
|
||||
|
||||
procedure TstUtils.TestCountChar;
|
||||
var
|
||||
currCount: Integer;
|
||||
i: Integer;
|
||||
begin
|
||||
for i:=Low(CountCharParams) to High(CountCharParams) do begin
|
||||
currCount := CountChar(CountCharParams[i].ch, CountCharParams[i].TestString);
|
||||
CheckEquals(CountCharParams[i].Count, currCount,
|
||||
'CountChar mismatch, test case ' + IntToStr(i));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TstUtils.TestFloatToRational;
|
||||
var
|
||||
currR: TExifRational;
|
||||
i: Integer;
|
||||
begin
|
||||
for i:=Low(FloatToRationalParams) to High(FloatToRationalParams) do
|
||||
with FloatToRationalParams[i] do begin
|
||||
currR := FloatToRational(Value, Precision);
|
||||
case Error of
|
||||
0: begin
|
||||
CheckEquals(currR.Numerator, Num,
|
||||
'FloatToRational numerator mismatch, test case ' + IntToStr(i));
|
||||
CheckEquals(currR.Denominator, Denom,
|
||||
'FloatToRational denominator mismatch, test case ' + IntToStr(i));
|
||||
end;
|
||||
1: CheckNotEquals(currR.Numerator, Num,
|
||||
'Unexpected FloatToRational numerator match, test case ' + IntToStr(i));
|
||||
2: CheckNotEquals(currR.Denominator, Denom,
|
||||
'Unexpected FloatToRational denominator match, test case ' + IntToStr(i));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TstUtils.TestInsertSpaces;
|
||||
var
|
||||
currStr: String;
|
||||
i: Integer;
|
||||
begin
|
||||
for i:=Low(InsertSpacesParams) to High(InsertSpacesParams) do begin
|
||||
currStr := InsertSpaces(InsertSpacesParams[i].TestString);
|
||||
CheckEquals(InsertSpacesParams[i].ResultString, currStr,
|
||||
'InsertSpaces mismatch, test case ' + IntToStr(i));
|
||||
end;
|
||||
end;
|
||||
|
||||
function SameIntegerKey(AKey1, AKey2: String): Boolean;
|
||||
var
|
||||
k1, k2: Integer;
|
||||
begin
|
||||
Result := TryStrToInt(AKey1, k1) and TryStrToInt(AKey2, k2) and (k1 = k2);
|
||||
end;
|
||||
|
||||
function SameStringKey(AKey1, AKey2: String): Boolean;
|
||||
begin
|
||||
Result := SameText(AKey1, AKey2);
|
||||
end;
|
||||
|
||||
procedure TstUtils.TestLookup;
|
||||
var
|
||||
currResult: String;
|
||||
i: Integer;
|
||||
begin
|
||||
for i:=Low(LookupParams) to High(LookupParams) do
|
||||
with LookupParams[i] do begin
|
||||
if SearchForKey then
|
||||
currResult := LookupValue(SearchStr, LkupTbl, @SameIntegerKey)
|
||||
else
|
||||
currResult := LookupKey(SearchStr, LkupTbl, @SameStringKey);
|
||||
CheckEquals(ResultStr, currResult,
|
||||
'Lookup mismatch, test case ' + IntToStr(i));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TstUtils.TestSplit;
|
||||
var
|
||||
currResult: TStringArray;
|
||||
i, j: Integer;
|
||||
begin
|
||||
for i:=Low(SplitParams) to High(SplitParams) do
|
||||
with SplitParams[i] do begin
|
||||
currResult := Split(Text, Sep);
|
||||
CheckEquals(NumParts, Length(currResult), 'Split count mismatch');
|
||||
for j:=0 to NumParts-1 do
|
||||
CheckEquals(Parts[j], currResult[j], 'Split mismatch in array element #' + IntToStr(j));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TstUtils.TestSplitGPS;
|
||||
const
|
||||
EPS = 1E-6;
|
||||
var
|
||||
currDeg, currMin, currSec: Double;
|
||||
i: Integer;
|
||||
begin
|
||||
for i:=Low(SplitGPSParams) to High(SplitGPSParams) do
|
||||
with SplitGPSParams[i] do begin
|
||||
SplitGPS(Value, currDeg, currMin, currSec);
|
||||
CheckEquals(Degs, currDeg, EPS, 'Degree value mismatch, test case ' + IntToStr(i));
|
||||
CheckEquals(Mins, currMin, EPS, 'Minutes mismatch, test case ' + IntToStr(i));
|
||||
CheckEquals(Secs, currSec, EPS, 'Seconds value mismatch, test case ' + IntToStr(i));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TstUtils.TestStrToGPS;
|
||||
const
|
||||
EPS = 1E-8;
|
||||
var
|
||||
currDeg: Double;
|
||||
i: Integer;
|
||||
currOK: Boolean;
|
||||
begin
|
||||
for i:=Low(StrToGpsParams) to High(StrToGpsParams) do begin
|
||||
with StrToGpsParams[i] do begin
|
||||
currOK := TryStrToGps(Text, currDeg);
|
||||
CheckEquals(Valid, currOK, 'GPS result validity mismatch, test case ' + IntToStr(i));
|
||||
if Valid then
|
||||
CheckEquals(Degs, currDeg, EPS, 'GPS degress mismatch, test case ' + IntToStr(i));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TstUtils.TestStrToRational;
|
||||
var
|
||||
currR: TExifRational;
|
||||
i: Integer;
|
||||
begin
|
||||
for i:=Low(StrToRationalParams) to High(StrToRationalParams) do
|
||||
with StrToRationalParams[i] do begin
|
||||
currR := StrToRational(Value);
|
||||
CheckEquals(currR.Numerator, Num,
|
||||
'StrToRational numerator mismatch, test case ' + IntToStr(i));
|
||||
CheckEquals(currR.Denominator, Denom,
|
||||
'StrToRational denominator mismatch, test case ' + IntToStr(i));
|
||||
end;
|
||||
end;
|
||||
|
||||
initialization
|
||||
{$IFDEF FPC}
|
||||
RegisterTest(TstUtils);
|
||||
{$ELSE}
|
||||
TestFramework.RegisterTest(TstUtils.Suite);
|
||||
{$ENDIF}
|
||||
|
||||
end.
|
||||
|
Reference in New Issue
Block a user