unit jsonconftest; {$mode objfpc}{$H+} {$codepage utf8} interface uses Classes, SysUtils, fpcunit, testutils, testregistry, jsonconf; type { TTestJSONConfig } TTestJSONConfig= class(TTestCase) Private procedure AssertStrings(Msg: String; L: TStrings; const Values: array of string); Function CreateConf(AFileName : String) : TJSONCOnfig; Procedure DeleteConf(C : TJSONConfig; DeleteConfFile : Boolean = true); published procedure TestDataTypes; procedure TestSubNodes; procedure TestEnumSubkeys; procedure TestEnumValues; procedure TestClear; procedure TestKey; procedure TestStrings; procedure TestUnicodeStrings; procedure TestUnicodeStrings2; end; implementation function TTestJSONConfig.CreateConf(AFileName: String): TJSONCOnfig; begin Result:=TJSONConfig.Create(Nil); Result.FileName:=AFileName; end; procedure TTestJSONConfig.DeleteConf(C: TJSONConfig; DeleteConfFile: Boolean); Var FN : String; begin If DeleteConfFile then FN:=C.FileName; FreeAndNil(C); If DeleteConfFile then DeleteFile(FN); end; procedure TTestJSONConfig.TestDataTypes; Const A = Integer(1); B = 'A string'; C = 1.23; D = True; E = Int64($FFFFFFFFFFFFF); Var Co : TJSONCOnfig; begin Co:=CreateConf('test.json'); try Co.SetValue('a',a); AssertEquals('Integer read/Write',a,Co.GetValue('a',0)); Co.SetValue('b',b); AssertEquals('String read/Write',b,Co.GetValue('b','')); Co.SetValue('c',C); AssertEquals('Float read/Write',c,Co.GetValue('c',0.0),0.01); Co.SetValue('d',d); AssertEquals('Boolean read/Write',d,Co.GetValue('d',False)); Co.SetValue('e',E); AssertEquals('Int64 read/Write',e,Co.GetValue('e',Int64(0))); Co.Flush; finally DeleteConf(Co,True); end; end; procedure TTestJSONConfig.TestSubNodes; Var C : TJSONCOnfig; begin C:=CreateConf('test.json'); try C.SetValue('a',1); AssertEquals('Read at root',1,C.GetValue('a',0)); C.SetValue('b/a',2); AssertEquals('Read at root',2,C.GetValue('b/a',2)); C.SetValue('b/c/a',3); AssertEquals('Read at root',3,C.GetValue('b/c/a',3)); finally DeleteConf(C,True); end; end; procedure TTestJSONConfig.TestEnumSubkeys; Var C : TJSONCOnfig; L : TStringList; begin C:=CreateConf('test.json'); try C.SetValue('/a',1); C.SetValue('/b/a',2); C.SetValue('/b/b',2); C.SetValue('/c/a',3); C.SetValue('/c/b/a',4); C.SetValue('/c/c/a',4); C.SetValue('/c/d/d',4); L:=TStringList.Create; try C.EnumSubKeys('/',L); If (L.Count<>2) then Fail('EnumSubkeys count'); If (L[0]<>'b') then Fail('EnumSubkeys first element'); If (L[1]<>'c') then Fail('EnumSubkeys second element'); finally L.Free; end; finally DeleteConf(C,True); end; end; procedure TTestJSONConfig.TestEnumValues; Var C : TJSONCOnfig; L : TStringList; begin C:=CreateConf('test.json'); try C.SetValue('/a',1); C.SetValue('/b/a',2); C.SetValue('/b/b',2); C.SetValue('/c/a',3); C.SetValue('/c/b/a',4); C.SetValue('/c/c/a',4); C.SetValue('/c/d/d',4); L:=TStringList.Create; try C.EnumValues('/',L); If (L.Count<>1) then Fail('EnumValues count'); If (L[0]<>'a') then Fail('EnumValues first element'); L.Clear; C.EnumValues('/b',L); If (L.Count<>2) then Fail('EnumValues subkey count'); If (L[0]<>'a') then Fail('EnumValues subkey first element'); If (L[1]<>'b') then Fail('EnumValues subkey second element'); finally L.Free; end; finally DeleteConf(C,True); end; end; procedure TTestJSONConfig.TestClear; Var C : TJSONCOnfig; begin C:=CreateConf('test.json'); try C.SetValue('a',1); C.Flush; C.DeleteValue('a'); AssertEquals('Modified set',True,C.Modified); AssertEquals('Delete value',0,C.GetValue('a',0)); C.SetValue('b/a',1); C.SetValue('b/c',2); C.DeleteValue('b/a'); AssertEquals('Delete value in subkey',0,C.GetValue('a',0)); AssertEquals('Delete value only clears deleted value',2,C.GetValue('b/c',0)); C.SetValue('b/a',1); C.Flush; C.DeletePath('b'); AssertEquals('Modified set',True,C.Modified); AssertEquals('Delete path',0,C.GetValue('b/a',0)); AssertEquals('Delete path deletes all values',0,C.GetValue('b/c',0)); C.Clear; AssertEquals('Clear',0,C.GetValue('/a',0)); finally DeleteConf(C,True); end; end; procedure TTestJSONConfig.TestKey; Var C : TJSONCOnfig; L : TStrings; begin C:=CreateConf('test.json'); try C.SetValue('a',1); C.SetValue('b/a',2); C.SetValue('b/b',2); C.SetValue('b/c/a',3); C.SetValue('b/c/b',3); C.OpenKey('/b',False); AssertEquals('Read relative to key a',2,C.GetValue('a',0)); AssertEquals('Read relative to key b',2,C.GetValue('b',0)); AssertEquals('Read in subkey relative to key a',3,C.GetValue('c/a',0)); AssertEquals('Read in subkey relative to key b',3,C.GetValue('c/b',0)); AssertEquals('Read absolute, disregarding key',1,C.GetValue('/a',0)); AssertEquals('Read absolute in subkey, disregarding key',2,C.GetValue('/b/a',0)); AssertEquals('Read absolute in subkeys, disregarding key',3,C.GetValue('/b/c/a',0)); C.CloseKey; AssertEquals('Closekey',1,C.GetValue('a',0)); C.OpenKey('b',False); C.OpenKey('c',False); AssertEquals('Open relative key',3,C.GetValue('a',0)); C.ResetKey; AssertEquals('ResetKey',1,C.GetValue('a',0)); C.Clear; L:=TStringList.Create; try C.EnumSubKeys('/',L); If (L.Count<>0) then Fail('clear failed'); C.OpenKey('/a/b/c/d',true); C.EnumSubKeys('/a',L); If (L.Count<>1) then Fail('Open key with allowcreate, level 1'); If (L[0]<>'b') then Fail('Open key with allowcreate, level 1'); L.Clear; C.EnumSubKeys('/a/b',L); If (L.Count<>1) then Fail('Open key with allowcreate, level 2'); If (L[0]<>'c') then Fail('Open key with allowcreate, level 2'); L.Clear; C.EnumSubKeys('/a/b/c',L); If (L.Count<>1) then Fail('Open key with allowcreate, level 3'); If (L[0]<>'d') then Fail('Open key with allowcreate, level 3'); finally L.Free; end; finally DeleteConf(C,True); end; end; procedure TTestJSONConfig.AssertStrings(Msg: String; L: TStrings; const Values: array of string); Var I : Integer; begin Msg:=Msg+': '; AssertNotNull(Msg+'Have strings',L); AssertEquals(Msg+'Correct element count',Length(Values),L.Count); For I:=0 to L.Count-1 do AssertEquals(Msg+'element '+IntToStr(i),Values[i],l[i]); end; procedure TTestJSONConfig.TestStrings; Var C : TJSONCOnfig; L,LD : TStrings; begin L:=Nil; LD:=Nil; C:=CreateConf('test.json'); try L:=TStringList.Create; LD:=TStringList.Create; L.Add('abc'); C.GetValue('list',L,''); AssertStrings('Clear, no default.',L,[]); C.GetValue('list',L,'text'); AssertStrings('Use default.',L,['text']); L.Clear; L.Add('abc'); L.Add('def'); C.SetValue('a',L); C.GetValue('a',LD,''); AssertStrings('List',LD,['abc','def']); L.Clear; L.Add('abc=1'); L.Add('def=2'); C.SetValue('a',L,True); LD.Clear; C.GetValue('a',LD,''); AssertStrings('List',LD,['abc=1','def=2']); C.SetValue('a','abc'); C.GetValue('a',L,''); AssertStrings('String',L,['abc']); C.SetValue('a',Integer(1)); C.GetValue('a',L,''); AssertStrings('integer',L,['1']); C.SetValue('a',True); C.GetValue('a',L,''); AssertStrings('integer',L,['True']); C.SetValue('a',Int64(1)); C.GetValue('a',L,''); AssertStrings('int64',L,['1']); finally L.Free; DeleteConf(C,True); end; end; procedure TTestJSONConfig.TestUnicodeStrings; Const utf8str = 'Größe ÄÜÖ ㎰ す 가'; utf8path = 'Größe/す가'; Var Co : TJSONCOnfig; begin Co:=CreateConf('test.json'); try Co.SetValue('a',utf8str); Co.SetValue(utf8path,'something'); Co.Flush; finally co.Free; end; Co:=CreateConf('test.json'); try AssertEquals('UTF8 string read/Write',utf8str,utf8encode(Co.GetValue('a',''))); AssertEquals('UTF8 path read/Write','something',Co.GetValue(utf8path,'something')); finally DeleteConf(Co,True); end; end; procedure TTestJSONConfig.TestUnicodeStrings2; Const utf8str = 'Größe ÄÜÖ ㎰ す 가'; utf8path = 'Größe/す가'; Var Co : TJSONCOnfig; begin Co:=CreateConf('test.json'); try Co.SetValue('/проверка',utf8str); Co.SetValue(utf8path,'something'); Co.Flush; finally co.Free; end; Co:=CreateConf('test.json'); try AssertEquals('UTF8 string read/Write',utf8str,utf8encode(Co.GetValue('/проверка',''))); AssertEquals('UTF8 path read/Write','something',Co.GetValue(utf8path,'something')); finally DeleteConf(Co,True); end; end; initialization RegisterTest(TTestJSONConfig); end.