fileconf.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name: tests/fileconf/fileconf.cpp
  3. // Purpose: wxFileConf unit test
  4. // Author: Vadim Zeitlin
  5. // Created: 2004-09-19
  6. // Copyright: (c) 2004 Vadim Zeitlin
  7. ///////////////////////////////////////////////////////////////////////////////
  8. // ----------------------------------------------------------------------------
  9. // headers
  10. // ----------------------------------------------------------------------------
  11. #include "testprec.h"
  12. #ifdef __BORLANDC__
  13. #pragma hdrstop
  14. #endif
  15. #if wxUSE_FILECONFIG
  16. #ifndef WX_PRECOMP
  17. #endif // WX_PRECOMP
  18. #include "wx/fileconf.h"
  19. #include "wx/sstream.h"
  20. #include "wx/log.h"
  21. static const wxChar *testconfig =
  22. wxT("[root]\n")
  23. wxT("entry=value\n")
  24. wxT("[root/group1]\n")
  25. wxT("[root/group1/subgroup]\n")
  26. wxT("subentry=subvalue\n")
  27. wxT("subentry2=subvalue2\n")
  28. wxT("[root/group2]\n")
  29. ;
  30. // ----------------------------------------------------------------------------
  31. // local functions
  32. // ----------------------------------------------------------------------------
  33. static wxString Dump(wxFileConfig& fc)
  34. {
  35. wxStringOutputStream sos;
  36. fc.Save(sos);
  37. return wxTextFile::Translate(sos.GetString(), wxTextFileType_Unix);
  38. }
  39. // helper macro to test wxFileConfig contents
  40. #define wxVERIFY_FILECONFIG(t, fc) CPPUNIT_ASSERT_EQUAL(wxString(t), Dump(fc))
  41. // ----------------------------------------------------------------------------
  42. // test class
  43. // ----------------------------------------------------------------------------
  44. class FileConfigTestCase : public CppUnit::TestCase
  45. {
  46. public:
  47. FileConfigTestCase() { }
  48. private:
  49. CPPUNIT_TEST_SUITE( FileConfigTestCase );
  50. CPPUNIT_TEST( Path );
  51. CPPUNIT_TEST( AddEntries );
  52. CPPUNIT_TEST( GetEntries );
  53. CPPUNIT_TEST( GetGroups );
  54. CPPUNIT_TEST( HasEntry );
  55. CPPUNIT_TEST( HasGroup );
  56. CPPUNIT_TEST( Binary );
  57. CPPUNIT_TEST( Save );
  58. CPPUNIT_TEST( DeleteEntry );
  59. CPPUNIT_TEST( DeleteAndWriteEntry );
  60. CPPUNIT_TEST( DeleteLastRootEntry );
  61. CPPUNIT_TEST( DeleteGroup );
  62. CPPUNIT_TEST( DeleteAll );
  63. CPPUNIT_TEST( RenameEntry );
  64. CPPUNIT_TEST( RenameGroup );
  65. CPPUNIT_TEST( CreateEntriesAndSubgroup );
  66. CPPUNIT_TEST( CreateSubgroupAndEntries );
  67. CPPUNIT_TEST( DeleteLastGroup );
  68. CPPUNIT_TEST( DeleteAndRecreateGroup );
  69. CPPUNIT_TEST( AddToExistingRoot );
  70. CPPUNIT_TEST( ReadNonExistent );
  71. CPPUNIT_TEST( ReadEmpty );
  72. CPPUNIT_TEST( ReadFloat );
  73. CPPUNIT_TEST_SUITE_END();
  74. void Path();
  75. void AddEntries();
  76. void GetEntries();
  77. void GetGroups();
  78. void HasEntry();
  79. void HasGroup();
  80. void Binary();
  81. void Save();
  82. void DeleteEntry();
  83. void DeleteAndWriteEntry();
  84. void DeleteLastRootEntry();
  85. void DeleteGroup();
  86. void DeleteAll();
  87. void RenameEntry();
  88. void RenameGroup();
  89. void CreateEntriesAndSubgroup();
  90. void CreateSubgroupAndEntries();
  91. void DeleteLastGroup();
  92. void DeleteAndRecreateGroup();
  93. void AddToExistingRoot();
  94. void ReadNonExistent();
  95. void ReadEmpty();
  96. void ReadFloat();
  97. static wxString ChangePath(wxFileConfig& fc, const wxChar *path)
  98. {
  99. fc.SetPath(path);
  100. return fc.GetPath();
  101. }
  102. void CheckGroupEntries(const wxFileConfig& fc,
  103. const wxChar *path,
  104. size_t nEntries,
  105. ...);
  106. void CheckGroupSubgroups(const wxFileConfig& fc,
  107. const wxChar *path,
  108. size_t nGroups,
  109. ...);
  110. DECLARE_NO_COPY_CLASS(FileConfigTestCase)
  111. };
  112. // register in the unnamed registry so that these tests are run by default
  113. CPPUNIT_TEST_SUITE_REGISTRATION( FileConfigTestCase );
  114. // also include in its own registry so that these tests can be run alone
  115. CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileConfigTestCase, "FileConfigTestCase" );
  116. void FileConfigTestCase::Path()
  117. {
  118. wxStringInputStream sis(testconfig);
  119. wxFileConfig fc(sis);
  120. CPPUNIT_ASSERT( ChangePath(fc, wxT("")) == wxT("") );
  121. CPPUNIT_ASSERT( ChangePath(fc, wxT("/")) == wxT("") );
  122. CPPUNIT_ASSERT( ChangePath(fc, wxT("root")) == wxT("/root") );
  123. CPPUNIT_ASSERT( ChangePath(fc, wxT("/root")) == wxT("/root") );
  124. CPPUNIT_ASSERT( ChangePath(fc, wxT("/root/group1/subgroup")) == wxT("/root/group1/subgroup") );
  125. CPPUNIT_ASSERT( ChangePath(fc, wxT("/root/group2")) == wxT("/root/group2") );
  126. }
  127. void FileConfigTestCase::AddEntries()
  128. {
  129. wxFileConfig fc;
  130. wxVERIFY_FILECONFIG( wxT(""), fc );
  131. fc.Write(wxT("/Foo"), wxT("foo"));
  132. wxVERIFY_FILECONFIG( wxT("Foo=foo\n"), fc );
  133. fc.Write(wxT("/Bar/Baz"), wxT("baz"));
  134. wxVERIFY_FILECONFIG( wxT("Foo=foo\n[Bar]\nBaz=baz\n"), fc );
  135. fc.DeleteAll();
  136. wxVERIFY_FILECONFIG( wxT(""), fc );
  137. fc.Write(wxT("/Bar/Baz"), wxT("baz"));
  138. wxVERIFY_FILECONFIG( wxT("[Bar]\nBaz=baz\n"), fc );
  139. fc.Write(wxT("/Foo"), wxT("foo"));
  140. wxVERIFY_FILECONFIG( wxT("Foo=foo\n[Bar]\nBaz=baz\n"), fc );
  141. }
  142. void
  143. FileConfigTestCase::CheckGroupEntries(const wxFileConfig& fc,
  144. const wxChar *path,
  145. size_t nEntries,
  146. ...)
  147. {
  148. wxConfigPathChanger change(&fc, wxString(path) + wxT("/"));
  149. CPPUNIT_ASSERT( fc.GetNumberOfEntries() == nEntries );
  150. va_list ap;
  151. va_start(ap, nEntries);
  152. long cookie;
  153. wxString name;
  154. for ( bool cont = fc.GetFirstEntry(name, cookie);
  155. cont;
  156. cont = fc.GetNextEntry(name, cookie), nEntries-- )
  157. {
  158. CPPUNIT_ASSERT( name == va_arg(ap, wxChar *) );
  159. }
  160. CPPUNIT_ASSERT( nEntries == 0 );
  161. va_end(ap);
  162. }
  163. void
  164. FileConfigTestCase::CheckGroupSubgroups(const wxFileConfig& fc,
  165. const wxChar *path,
  166. size_t nGroups,
  167. ...)
  168. {
  169. wxConfigPathChanger change(&fc, wxString(path) + wxT("/"));
  170. CPPUNIT_ASSERT( fc.GetNumberOfGroups() == nGroups );
  171. va_list ap;
  172. va_start(ap, nGroups);
  173. long cookie;
  174. wxString name;
  175. for ( bool cont = fc.GetFirstGroup(name, cookie);
  176. cont;
  177. cont = fc.GetNextGroup(name, cookie), nGroups-- )
  178. {
  179. CPPUNIT_ASSERT( name == va_arg(ap, wxChar *) );
  180. }
  181. CPPUNIT_ASSERT( nGroups == 0 );
  182. va_end(ap);
  183. }
  184. void FileConfigTestCase::GetEntries()
  185. {
  186. wxStringInputStream sis(testconfig);
  187. wxFileConfig fc(sis);
  188. CheckGroupEntries(fc, wxT(""), 0);
  189. CheckGroupEntries(fc, wxT("/root"), 1, wxT("entry"));
  190. CheckGroupEntries(fc, wxT("/root/group1"), 0);
  191. CheckGroupEntries(fc, wxT("/root/group1/subgroup"),
  192. 2, wxT("subentry"), wxT("subentry2"));
  193. }
  194. void FileConfigTestCase::GetGroups()
  195. {
  196. wxStringInputStream sis(testconfig);
  197. wxFileConfig fc(sis);
  198. CheckGroupSubgroups(fc, wxT(""), 1, wxT("root"));
  199. CheckGroupSubgroups(fc, wxT("/root"), 2, wxT("group1"), wxT("group2"));
  200. CheckGroupSubgroups(fc, wxT("/root/group1"), 1, wxT("subgroup"));
  201. CheckGroupSubgroups(fc, wxT("/root/group2"), 0);
  202. }
  203. void FileConfigTestCase::HasEntry()
  204. {
  205. wxStringInputStream sis(testconfig);
  206. wxFileConfig fc(sis);
  207. CPPUNIT_ASSERT( !fc.HasEntry(wxT("root")) );
  208. CPPUNIT_ASSERT( fc.HasEntry(wxT("root/entry")) );
  209. CPPUNIT_ASSERT( fc.HasEntry(wxT("/root/entry")) );
  210. CPPUNIT_ASSERT( fc.HasEntry(wxT("root/group1/subgroup/subentry")) );
  211. CPPUNIT_ASSERT( !fc.HasEntry(wxT("")) );
  212. CPPUNIT_ASSERT( !fc.HasEntry(wxT("root/group1")) );
  213. CPPUNIT_ASSERT( !fc.HasEntry(wxT("subgroup/subentry")) );
  214. CPPUNIT_ASSERT( !fc.HasEntry(wxT("/root/no_such_group/entry")) );
  215. CPPUNIT_ASSERT( !fc.HasGroup(wxT("/root/no_such_group")) );
  216. }
  217. void FileConfigTestCase::HasGroup()
  218. {
  219. wxStringInputStream sis(testconfig);
  220. wxFileConfig fc(sis);
  221. CPPUNIT_ASSERT( fc.HasGroup(wxT("root")) );
  222. CPPUNIT_ASSERT( fc.HasGroup(wxT("root/group1")) );
  223. CPPUNIT_ASSERT( fc.HasGroup(wxT("root/group1/subgroup")) );
  224. CPPUNIT_ASSERT( fc.HasGroup(wxT("root/group2")) );
  225. CPPUNIT_ASSERT( !fc.HasGroup(wxT("")) );
  226. CPPUNIT_ASSERT( !fc.HasGroup(wxT("root/group")) );
  227. CPPUNIT_ASSERT( !fc.HasGroup(wxT("root//subgroup")) );
  228. CPPUNIT_ASSERT( !fc.HasGroup(wxT("foot/subgroup")) );
  229. CPPUNIT_ASSERT( !fc.HasGroup(wxT("foot")) );
  230. }
  231. void FileConfigTestCase::Binary()
  232. {
  233. wxStringInputStream sis(
  234. "[root]\n"
  235. "binary=Zm9vCg==\n"
  236. );
  237. wxFileConfig fc(sis);
  238. wxMemoryBuffer buf;
  239. fc.Read("/root/binary", &buf);
  240. CPPUNIT_ASSERT( memcmp("foo\n", buf.GetData(), buf.GetDataLen()) == 0 );
  241. buf.SetDataLen(0);
  242. buf.AppendData("\0\1\2", 3);
  243. fc.Write("/root/012", buf);
  244. wxVERIFY_FILECONFIG(
  245. "[root]\n"
  246. "binary=Zm9vCg==\n"
  247. "012=AAEC\n",
  248. fc
  249. );
  250. }
  251. void FileConfigTestCase::Save()
  252. {
  253. wxStringInputStream sis(testconfig);
  254. wxFileConfig fc(sis);
  255. wxVERIFY_FILECONFIG( testconfig, fc );
  256. }
  257. void FileConfigTestCase::DeleteEntry()
  258. {
  259. wxStringInputStream sis(testconfig);
  260. wxFileConfig fc(sis);
  261. CPPUNIT_ASSERT( !fc.DeleteEntry(wxT("foo")) );
  262. CPPUNIT_ASSERT( fc.DeleteEntry(wxT("root/group1/subgroup/subentry")) );
  263. wxVERIFY_FILECONFIG( wxT("[root]\n")
  264. wxT("entry=value\n")
  265. wxT("[root/group1]\n")
  266. wxT("[root/group1/subgroup]\n")
  267. wxT("subentry2=subvalue2\n")
  268. wxT("[root/group2]\n"),
  269. fc );
  270. // group should be deleted now as well as it became empty
  271. wxConfigPathChanger change(&fc, wxT("root/group1/subgroup/subentry2"));
  272. CPPUNIT_ASSERT( fc.DeleteEntry(wxT("subentry2")) );
  273. wxVERIFY_FILECONFIG( wxT("[root]\n")
  274. wxT("entry=value\n")
  275. wxT("[root/group1]\n")
  276. wxT("[root/group2]\n"),
  277. fc );
  278. }
  279. void FileConfigTestCase::DeleteAndWriteEntry()
  280. {
  281. wxStringInputStream sis(
  282. "[root/group1]\n"
  283. "subentry=subvalue\n"
  284. "subentry2=subvalue2\n"
  285. "subentry3=subvalue3\n"
  286. );
  287. wxFileConfig fc(sis);
  288. fc.DeleteEntry("/root/group1/subentry2");
  289. fc.Write("/root/group1/subentry2", "testvalue");
  290. fc.DeleteEntry("/root/group2/subentry2");
  291. fc.Write("/root/group2/subentry2", "testvalue2");
  292. fc.DeleteEntry("/root/group1/subentry2");
  293. fc.Write("/root/group1/subentry2", "testvalue");
  294. fc.DeleteEntry("/root/group2/subentry2");
  295. fc.Write("/root/group2/subentry2", "testvalue2");
  296. wxVERIFY_FILECONFIG( "[root/group1]\n"
  297. "subentry=subvalue\n"
  298. "subentry3=subvalue3\n"
  299. "subentry2=testvalue\n"
  300. "[root/group2]\n"
  301. "subentry2=testvalue2\n",
  302. fc );
  303. fc.DeleteEntry("/root/group2/subentry2");
  304. wxVERIFY_FILECONFIG( "[root/group1]\n"
  305. "subentry=subvalue\n"
  306. "subentry3=subvalue3\n"
  307. "subentry2=testvalue\n",
  308. fc );
  309. fc.DeleteEntry("/root/group1/subentry2");
  310. fc.DeleteEntry("/root/group1/subentry");
  311. fc.DeleteEntry("/root/group1/subentry3");
  312. wxVERIFY_FILECONFIG( "", fc );
  313. }
  314. void FileConfigTestCase::DeleteLastRootEntry()
  315. {
  316. // This tests for the bug which occurred when the last entry of the root
  317. // group was deleted: this corrupted internal state and resulted in a crash
  318. // after trying to write the just deleted entry again.
  319. wxStringInputStream sis("");
  320. wxFileConfig fc(sis);
  321. fc.Write("key", "value");
  322. wxVERIFY_FILECONFIG( "key=value\n", fc );
  323. fc.DeleteEntry("key");
  324. wxVERIFY_FILECONFIG( "", fc );
  325. fc.Write("key", "value");
  326. wxVERIFY_FILECONFIG( "key=value\n", fc );
  327. }
  328. void FileConfigTestCase::DeleteGroup()
  329. {
  330. wxStringInputStream sis(testconfig);
  331. wxFileConfig fc(sis);
  332. CPPUNIT_ASSERT( !fc.DeleteGroup(wxT("foo")) );
  333. CPPUNIT_ASSERT( fc.DeleteGroup(wxT("root/group1")) );
  334. wxVERIFY_FILECONFIG( wxT("[root]\n")
  335. wxT("entry=value\n")
  336. wxT("[root/group2]\n"),
  337. fc );
  338. // notice trailing slash: it should be ignored
  339. CPPUNIT_ASSERT( fc.DeleteGroup(wxT("root/group2/")) );
  340. wxVERIFY_FILECONFIG( wxT("[root]\n")
  341. wxT("entry=value\n"),
  342. fc );
  343. CPPUNIT_ASSERT( fc.DeleteGroup(wxT("root")) );
  344. CPPUNIT_ASSERT( Dump(fc).empty() );
  345. }
  346. void FileConfigTestCase::DeleteAll()
  347. {
  348. wxStringInputStream sis(testconfig);
  349. wxFileConfig fc(sis);
  350. CPPUNIT_ASSERT( fc.DeleteAll() );
  351. CPPUNIT_ASSERT( Dump(fc).empty() );
  352. }
  353. void FileConfigTestCase::RenameEntry()
  354. {
  355. wxStringInputStream sis(testconfig);
  356. wxFileConfig fc(sis);
  357. fc.SetPath(wxT("root"));
  358. CPPUNIT_ASSERT( fc.RenameEntry(wxT("entry"), wxT("newname")) );
  359. wxVERIFY_FILECONFIG( wxT("[root]\n")
  360. wxT("newname=value\n")
  361. wxT("[root/group1]\n")
  362. wxT("[root/group1/subgroup]\n")
  363. wxT("subentry=subvalue\n")
  364. wxT("subentry2=subvalue2\n")
  365. wxT("[root/group2]\n"),
  366. fc );
  367. fc.SetPath(wxT("group1/subgroup"));
  368. CPPUNIT_ASSERT( !fc.RenameEntry(wxT("entry"), wxT("newname")) );
  369. CPPUNIT_ASSERT( !fc.RenameEntry(wxT("subentry"), wxT("subentry2")) );
  370. CPPUNIT_ASSERT( fc.RenameEntry(wxT("subentry"), wxT("subentry1")) );
  371. wxVERIFY_FILECONFIG( wxT("[root]\n")
  372. wxT("newname=value\n")
  373. wxT("[root/group1]\n")
  374. wxT("[root/group1/subgroup]\n")
  375. wxT("subentry2=subvalue2\n")
  376. wxT("subentry1=subvalue\n")
  377. wxT("[root/group2]\n"),
  378. fc );
  379. }
  380. void FileConfigTestCase::RenameGroup()
  381. {
  382. wxStringInputStream sis(testconfig);
  383. wxFileConfig fc(sis);
  384. CPPUNIT_ASSERT( fc.RenameGroup(wxT("root"), wxT("foot")) );
  385. wxVERIFY_FILECONFIG( wxT("[foot]\n")
  386. wxT("entry=value\n")
  387. wxT("[foot/group1]\n")
  388. wxT("[foot/group1/subgroup]\n")
  389. wxT("subentry=subvalue\n")
  390. wxT("subentry2=subvalue2\n")
  391. wxT("[foot/group2]\n"),
  392. fc );
  393. // renaming a path doesn't work, it must be the immediate group
  394. CPPUNIT_ASSERT( !fc.RenameGroup(wxT("foot/group1"), wxT("group2")) );
  395. fc.SetPath(wxT("foot"));
  396. // renaming to a name of existing group doesn't work
  397. CPPUNIT_ASSERT( !fc.RenameGroup(wxT("group1"), wxT("group2")) );
  398. // try exchanging the groups names and then restore them back
  399. CPPUNIT_ASSERT( fc.RenameGroup(wxT("group1"), wxT("groupTmp")) );
  400. wxVERIFY_FILECONFIG( wxT("[foot]\n")
  401. wxT("entry=value\n")
  402. wxT("[foot/groupTmp]\n")
  403. wxT("[foot/groupTmp/subgroup]\n")
  404. wxT("subentry=subvalue\n")
  405. wxT("subentry2=subvalue2\n")
  406. wxT("[foot/group2]\n"),
  407. fc );
  408. CPPUNIT_ASSERT( fc.RenameGroup(wxT("group2"), wxT("group1")) );
  409. wxVERIFY_FILECONFIG( wxT("[foot]\n")
  410. wxT("entry=value\n")
  411. wxT("[foot/groupTmp]\n")
  412. wxT("[foot/groupTmp/subgroup]\n")
  413. wxT("subentry=subvalue\n")
  414. wxT("subentry2=subvalue2\n")
  415. wxT("[foot/group1]\n"),
  416. fc );
  417. CPPUNIT_ASSERT( fc.RenameGroup(wxT("groupTmp"), wxT("group2")) );
  418. wxVERIFY_FILECONFIG( wxT("[foot]\n")
  419. wxT("entry=value\n")
  420. wxT("[foot/group2]\n")
  421. wxT("[foot/group2/subgroup]\n")
  422. wxT("subentry=subvalue\n")
  423. wxT("subentry2=subvalue2\n")
  424. wxT("[foot/group1]\n"),
  425. fc );
  426. CPPUNIT_ASSERT( fc.RenameGroup(wxT("group1"), wxT("groupTmp")) );
  427. wxVERIFY_FILECONFIG( wxT("[foot]\n")
  428. wxT("entry=value\n")
  429. wxT("[foot/group2]\n")
  430. wxT("[foot/group2/subgroup]\n")
  431. wxT("subentry=subvalue\n")
  432. wxT("subentry2=subvalue2\n")
  433. wxT("[foot/groupTmp]\n"),
  434. fc );
  435. CPPUNIT_ASSERT( fc.RenameGroup(wxT("group2"), wxT("group1")) );
  436. wxVERIFY_FILECONFIG( wxT("[foot]\n")
  437. wxT("entry=value\n")
  438. wxT("[foot/group1]\n")
  439. wxT("[foot/group1/subgroup]\n")
  440. wxT("subentry=subvalue\n")
  441. wxT("subentry2=subvalue2\n")
  442. wxT("[foot/groupTmp]\n"),
  443. fc );
  444. CPPUNIT_ASSERT( fc.RenameGroup(wxT("groupTmp"), wxT("group2")) );
  445. wxVERIFY_FILECONFIG( wxT("[foot]\n")
  446. wxT("entry=value\n")
  447. wxT("[foot/group1]\n")
  448. wxT("[foot/group1/subgroup]\n")
  449. wxT("subentry=subvalue\n")
  450. wxT("subentry2=subvalue2\n")
  451. wxT("[foot/group2]\n"),
  452. fc );
  453. }
  454. void FileConfigTestCase::CreateSubgroupAndEntries()
  455. {
  456. wxFileConfig fc;
  457. fc.Write(wxT("sub/sub_first"), wxT("sub_one"));
  458. fc.Write(wxT("first"), wxT("one"));
  459. wxVERIFY_FILECONFIG( wxT("first=one\n")
  460. wxT("[sub]\n")
  461. wxT("sub_first=sub_one\n"),
  462. fc );
  463. }
  464. void FileConfigTestCase::CreateEntriesAndSubgroup()
  465. {
  466. wxFileConfig fc;
  467. fc.Write(wxT("first"), wxT("one"));
  468. fc.Write(wxT("second"), wxT("two"));
  469. fc.Write(wxT("sub/sub_first"), wxT("sub_one"));
  470. wxVERIFY_FILECONFIG( wxT("first=one\n")
  471. wxT("second=two\n")
  472. wxT("[sub]\n")
  473. wxT("sub_first=sub_one\n"),
  474. fc );
  475. }
  476. static void EmptyConfigAndWriteKey()
  477. {
  478. wxFileConfig fc(wxT("deleteconftest"));
  479. const wxString groupPath = wxT("/root");
  480. if ( fc.Exists(groupPath) )
  481. {
  482. // using DeleteGroup exposes the problem, using DeleteAll doesn't
  483. CPPUNIT_ASSERT( fc.DeleteGroup(groupPath) );
  484. }
  485. // the config must be empty for the problem to arise
  486. CPPUNIT_ASSERT( !fc.GetNumberOfEntries(true) );
  487. CPPUNIT_ASSERT( !fc.GetNumberOfGroups(true) );
  488. // this crashes on second call of this function
  489. CPPUNIT_ASSERT( fc.Write(groupPath + wxT("/entry"), wxT("value")) );
  490. }
  491. void FileConfigTestCase::DeleteLastGroup()
  492. {
  493. /*
  494. We make 2 of the same calls, first to create a file config with a single
  495. group and key...
  496. */
  497. ::EmptyConfigAndWriteKey();
  498. /*
  499. ... then the same but this time the key's group is deleted before the
  500. key is written again. This causes a crash.
  501. */
  502. ::EmptyConfigAndWriteKey();
  503. // clean up
  504. wxLogNull noLogging;
  505. (void) ::wxRemoveFile(wxFileConfig::GetLocalFileName(wxT("deleteconftest")));
  506. }
  507. void FileConfigTestCase::DeleteAndRecreateGroup()
  508. {
  509. static const wxChar *confInitial =
  510. wxT("[First]\n")
  511. wxT("Value1=Foo\n")
  512. wxT("[Second]\n")
  513. wxT("Value2=Bar\n");
  514. wxStringInputStream sis(confInitial);
  515. wxFileConfig fc(sis);
  516. fc.DeleteGroup(wxT("Second"));
  517. wxVERIFY_FILECONFIG( wxT("[First]\n")
  518. wxT("Value1=Foo\n"),
  519. fc );
  520. fc.Write(wxT("Second/Value2"), wxT("New"));
  521. wxVERIFY_FILECONFIG( wxT("[First]\n")
  522. wxT("Value1=Foo\n")
  523. wxT("[Second]\n")
  524. wxT("Value2=New\n"),
  525. fc );
  526. }
  527. void FileConfigTestCase::AddToExistingRoot()
  528. {
  529. static const wxChar *confInitial =
  530. wxT("[Group]\n")
  531. wxT("value1=foo\n");
  532. wxStringInputStream sis(confInitial);
  533. wxFileConfig fc(sis);
  534. fc.Write(wxT("/value1"), wxT("bar"));
  535. wxVERIFY_FILECONFIG(
  536. wxT("value1=bar\n")
  537. wxT("[Group]\n")
  538. wxT("value1=foo\n"),
  539. fc
  540. );
  541. }
  542. void FileConfigTestCase::ReadNonExistent()
  543. {
  544. static const char *confTest =
  545. "community=censored\n"
  546. "[City1]\n"
  547. "URL=www.fake1.na\n"
  548. "[City1/A1]\n"
  549. "[City1/A1/1]\n"
  550. "IP=192.168.1.66\n"
  551. "URL=www.fake2.na\n"
  552. ;
  553. wxStringInputStream sis(confTest);
  554. wxFileConfig fc(sis);
  555. wxString url;
  556. CPPUNIT_ASSERT( !fc.Read("URL", &url) );
  557. }
  558. void FileConfigTestCase::ReadEmpty()
  559. {
  560. static const char *confTest = "";
  561. wxStringInputStream sis(confTest);
  562. wxFileConfig fc(sis);
  563. }
  564. void FileConfigTestCase::ReadFloat()
  565. {
  566. static const char *confTest =
  567. "x=1.234\n"
  568. "y=-9876.5432\n"
  569. "z=2e+308\n"
  570. ;
  571. wxStringInputStream sis(confTest);
  572. wxFileConfig fc(sis);
  573. float f;
  574. CPPUNIT_ASSERT( fc.Read("x", &f) );
  575. CPPUNIT_ASSERT_EQUAL( 1.234f, f );
  576. CPPUNIT_ASSERT( fc.Read("y", &f) );
  577. CPPUNIT_ASSERT_EQUAL( -9876.5432f, f );
  578. }
  579. #endif // wxUSE_FILECONFIG