]> git.saurik.com Git - wxWidgets.git/blobdiff - tests/fileconf/fileconftest.cpp
Unicode compilation fix: wxStrlocale() doesn't take wide strings
[wxWidgets.git] / tests / fileconf / fileconftest.cpp
index 7b8216b75ed542b68bbfd6c354669c55e32e8eb6..6f4aa5ff5357d1d215a02f01a6f8ef62a4730e44 100644 (file)
@@ -11,7 +11,7 @@
 // headers
 // ----------------------------------------------------------------------------
 
-#include "wx/wxprec.h"
+#include "testprec.h"
 
 #ifdef __BORLANDC__
     #pragma hdrstop
@@ -24,8 +24,7 @@
 
 #include "wx/fileconf.h"
 #include "wx/sstream.h"
-
-#include "wx/cppunit.h"
+#include "wx/log.h"
 
 static const wxChar *testconfig =
 _T("[root]\n")
@@ -37,6 +36,20 @@ _T("subentry2=subvalue2\n")
 _T("[root/group2]\n")
 ;
 
+// ----------------------------------------------------------------------------
+// local functions
+// ----------------------------------------------------------------------------
+
+static wxString Dump(wxFileConfig& fc)
+{
+    wxStringOutputStream sos;
+    fc.Save(sos);
+    return wxTextFile::Translate(sos.GetString(), wxTextFileType_Unix);
+}
+
+// helper macro to test wxFileConfig contents
+#define wxVERIFY_FILECONFIG(t, fc) CPPUNIT_ASSERT_EQUAL(wxString(t), Dump(fc))
+
 // ----------------------------------------------------------------------------
 // test class
 // ----------------------------------------------------------------------------
@@ -60,6 +73,10 @@ private:
         CPPUNIT_TEST( DeleteAll );
         CPPUNIT_TEST( RenameEntry );
         CPPUNIT_TEST( RenameGroup );
+        CPPUNIT_TEST( CreateEntriesAndSubgroup );
+        CPPUNIT_TEST( CreateSubgroupAndEntries );
+        CPPUNIT_TEST( DeleteLastGroup );
+        CPPUNIT_TEST( DeleteAndRecreateGroup );
     CPPUNIT_TEST_SUITE_END();
 
     void Path();
@@ -74,6 +91,10 @@ private:
     void DeleteAll();
     void RenameEntry();
     void RenameGroup();
+    void CreateEntriesAndSubgroup();
+    void CreateSubgroupAndEntries();
+    void DeleteLastGroup();
+    void DeleteAndRecreateGroup();
 
     static wxString ChangePath(wxFileConfig& fc, const wxChar *path)
     {
@@ -82,13 +103,6 @@ private:
         return fc.GetPath();
     }
 
-    static wxString Dump(wxFileConfig& fc)
-    {
-        wxStringOutputStream sos;
-        fc.Save(sos);
-        return wxTextFile::Translate(sos.GetString(), wxTextFileType_Unix);
-    }
-
     void CheckGroupEntries(const wxFileConfig& fc,
                            const wxChar *path,
                            size_t nEntries,
@@ -124,22 +138,22 @@ void FileConfigTestCase::AddEntries()
 {
     wxFileConfig fc;
 
-    CPPUNIT_ASSERT( Dump(fc) == _T("") );
+    wxVERIFY_FILECONFIG( _T(""), fc  );
 
     fc.Write(_T("/Foo"), _T("foo"));
-    CPPUNIT_ASSERT( Dump(fc) == _T("Foo=foo\n") );
+    wxVERIFY_FILECONFIG( _T("Foo=foo\n"), fc  );
 
     fc.Write(_T("/Bar/Baz"), _T("baz"));
-    CPPUNIT_ASSERT( Dump(fc) == _T("Foo=foo\n[Bar]\nBaz=baz\n") );
+    wxVERIFY_FILECONFIG( _T("Foo=foo\n[Bar]\nBaz=baz\n"), fc  );
 
     fc.DeleteAll();
-    CPPUNIT_ASSERT( Dump(fc) == _T("") );
+    wxVERIFY_FILECONFIG( _T(""), fc  );
 
     fc.Write(_T("/Bar/Baz"), _T("baz"));
-    CPPUNIT_ASSERT( Dump(fc) == _T("[Bar]\nBaz=baz\n") );
+    wxVERIFY_FILECONFIG( _T("[Bar]\nBaz=baz\n"), fc  );
 
     fc.Write(_T("/Foo"), _T("foo"));
-    CPPUNIT_ASSERT( Dump(fc) == _T("Foo=foo\n[Bar]\nBaz=baz\n") );
+    wxVERIFY_FILECONFIG( _T("Foo=foo\n[Bar]\nBaz=baz\n"), fc  );
 }
 
 void
@@ -231,6 +245,8 @@ void FileConfigTestCase::HasEntry()
     CPPUNIT_ASSERT( !fc.HasEntry(_T("")) );
     CPPUNIT_ASSERT( !fc.HasEntry(_T("root/group1")) );
     CPPUNIT_ASSERT( !fc.HasEntry(_T("subgroup/subentry")) );
+    CPPUNIT_ASSERT( !fc.HasEntry(_T("/root/no_such_group/entry")) );
+    CPPUNIT_ASSERT( !fc.HasGroup(_T("/root/no_such_group")) );
 }
 
 void FileConfigTestCase::HasGroup()
@@ -242,17 +258,18 @@ void FileConfigTestCase::HasGroup()
     CPPUNIT_ASSERT( fc.HasGroup(_T("root/group1")) );
     CPPUNIT_ASSERT( fc.HasGroup(_T("root/group1/subgroup")) );
     CPPUNIT_ASSERT( fc.HasGroup(_T("root/group2")) );
-    CPPUNIT_ASSERT( !fc.HasGroup(_T("foot")) );
     CPPUNIT_ASSERT( !fc.HasGroup(_T("")) );
     CPPUNIT_ASSERT( !fc.HasGroup(_T("root/group")) );
     CPPUNIT_ASSERT( !fc.HasGroup(_T("root//subgroup")) );
+    CPPUNIT_ASSERT( !fc.HasGroup(_T("foot/subgroup")) );
+    CPPUNIT_ASSERT( !fc.HasGroup(_T("foot")) );
 }
 
 void FileConfigTestCase::Save()
 {
     wxStringInputStream sis(testconfig);
     wxFileConfig fc(sis);
-    CPPUNIT_ASSERT( Dump(fc) == testconfig );
+    wxVERIFY_FILECONFIG( testconfig, fc );
 }
 
 void FileConfigTestCase::DeleteEntry()
@@ -263,20 +280,22 @@ void FileConfigTestCase::DeleteEntry()
     CPPUNIT_ASSERT( !fc.DeleteEntry(_T("foo")) );
 
     CPPUNIT_ASSERT( fc.DeleteEntry(_T("root/group1/subgroup/subentry")) );
-    CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n")
-                                _T("entry=value\n")
-                                _T("[root/group1]\n")
-                                _T("[root/group1/subgroup]\n")
-                                _T("subentry2=subvalue2\n")
-                                _T("[root/group2]\n") );
+    wxVERIFY_FILECONFIG( _T("[root]\n")
+                         _T("entry=value\n")
+                         _T("[root/group1]\n")
+                         _T("[root/group1/subgroup]\n")
+                         _T("subentry2=subvalue2\n")
+                         _T("[root/group2]\n"),
+                         fc );
 
     // group should be deleted now as well as it became empty
     wxConfigPathChanger change(&fc, _T("root/group1/subgroup/subentry2"));
     CPPUNIT_ASSERT( fc.DeleteEntry(_T("subentry2")) );
-    CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n")
-                                _T("entry=value\n")
-                                _T("[root/group1]\n")
-                                _T("[root/group2]\n") );
+    wxVERIFY_FILECONFIG( _T("[root]\n")
+                         _T("entry=value\n")
+                         _T("[root/group1]\n")
+                         _T("[root/group2]\n"),
+                         fc );
 }
 
 void FileConfigTestCase::DeleteGroup()
@@ -287,13 +306,16 @@ void FileConfigTestCase::DeleteGroup()
     CPPUNIT_ASSERT( !fc.DeleteGroup(_T("foo")) );
 
     CPPUNIT_ASSERT( fc.DeleteGroup(_T("root/group1")) );
-    CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n")
-                                _T("entry=value\n")
-                                _T("[root/group2]\n") );
+    wxVERIFY_FILECONFIG( _T("[root]\n")
+                         _T("entry=value\n")
+                         _T("[root/group2]\n"),
+                         fc );
 
-    CPPUNIT_ASSERT( fc.DeleteGroup(_T("root/group2")) );
-    CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n")
-                                _T("entry=value\n") );
+    // notice trailing slash: it should be ignored
+    CPPUNIT_ASSERT( fc.DeleteGroup(_T("root/group2/")) );
+    wxVERIFY_FILECONFIG( _T("[root]\n")
+                         _T("entry=value\n"),
+                         fc );
 
     CPPUNIT_ASSERT( fc.DeleteGroup(_T("root")) );
     CPPUNIT_ASSERT( Dump(fc).empty() );
@@ -315,26 +337,28 @@ void FileConfigTestCase::RenameEntry()
 
     fc.SetPath(_T("root"));
     CPPUNIT_ASSERT( fc.RenameEntry(_T("entry"), _T("newname")) );
-    CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n")
-                                _T("newname=value\n")
-                                _T("[root/group1]\n")
-                                _T("[root/group1/subgroup]\n")
-                                _T("subentry=subvalue\n")
-                                _T("subentry2=subvalue2\n")
-                                _T("[root/group2]\n") );
+    wxVERIFY_FILECONFIG( _T("[root]\n")
+                         _T("newname=value\n")
+                         _T("[root/group1]\n")
+                         _T("[root/group1/subgroup]\n")
+                         _T("subentry=subvalue\n")
+                         _T("subentry2=subvalue2\n")
+                         _T("[root/group2]\n"),
+                         fc );
 
     fc.SetPath(_T("group1/subgroup"));
     CPPUNIT_ASSERT( !fc.RenameEntry(_T("entry"), _T("newname")) );
     CPPUNIT_ASSERT( !fc.RenameEntry(_T("subentry"), _T("subentry2")) );
 
     CPPUNIT_ASSERT( fc.RenameEntry(_T("subentry"), _T("subentry1")) );
-    CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n")
-                                _T("newname=value\n")
-                                _T("[root/group1]\n")
-                                _T("[root/group1/subgroup]\n")
-                                _T("subentry2=subvalue2\n")
-                                _T("subentry1=subvalue\n")
-                                _T("[root/group2]\n") );
+    wxVERIFY_FILECONFIG( _T("[root]\n")
+                         _T("newname=value\n")
+                         _T("[root/group1]\n")
+                         _T("[root/group1/subgroup]\n")
+                         _T("subentry2=subvalue2\n")
+                         _T("subentry1=subvalue\n")
+                         _T("[root/group2]\n"),
+                         fc );
 }
 
 void FileConfigTestCase::RenameGroup()
@@ -343,13 +367,175 @@ void FileConfigTestCase::RenameGroup()
     wxFileConfig fc(sis);
 
     CPPUNIT_ASSERT( fc.RenameGroup(_T("root"), _T("foot")) );
-    CPPUNIT_ASSERT( Dump(fc) == _T("[foot]\n")
-                                _T("entry=value\n")
-                                _T("[foot/group1]\n")
-                                _T("[foot/group1/subgroup]\n")
-                                _T("subentry=subvalue\n")
-                                _T("subentry2=subvalue2\n")
-                                _T("[foot/group2]\n") );
+    wxVERIFY_FILECONFIG( _T("[foot]\n")
+                         _T("entry=value\n")
+                         _T("[foot/group1]\n")
+                         _T("[foot/group1/subgroup]\n")
+                         _T("subentry=subvalue\n")
+                         _T("subentry2=subvalue2\n")
+                         _T("[foot/group2]\n"),
+                         fc );
+
+    // renaming a path doesn't work, it must be the immediate group
+    CPPUNIT_ASSERT( !fc.RenameGroup(_T("foot/group1"), _T("group2")) );
+
+
+    fc.SetPath(_T("foot"));
+
+    // renaming to a name of existing group doesn't work
+    CPPUNIT_ASSERT( !fc.RenameGroup(_T("group1"), _T("group2")) );
+
+    // try exchanging the groups names and then restore them back
+    CPPUNIT_ASSERT( fc.RenameGroup(_T("group1"), _T("groupTmp")) );
+    wxVERIFY_FILECONFIG( _T("[foot]\n")
+                         _T("entry=value\n")
+                         _T("[foot/groupTmp]\n")
+                         _T("[foot/groupTmp/subgroup]\n")
+                         _T("subentry=subvalue\n")
+                         _T("subentry2=subvalue2\n")
+                         _T("[foot/group2]\n"),
+                         fc );
+
+    CPPUNIT_ASSERT( fc.RenameGroup(_T("group2"), _T("group1")) );
+    wxVERIFY_FILECONFIG( _T("[foot]\n")
+                         _T("entry=value\n")
+                         _T("[foot/groupTmp]\n")
+                         _T("[foot/groupTmp/subgroup]\n")
+                         _T("subentry=subvalue\n")
+                         _T("subentry2=subvalue2\n")
+                         _T("[foot/group1]\n"),
+                         fc );
+
+    CPPUNIT_ASSERT( fc.RenameGroup(_T("groupTmp"), _T("group2")) );
+    wxVERIFY_FILECONFIG( _T("[foot]\n")
+                         _T("entry=value\n")
+                         _T("[foot/group2]\n")
+                         _T("[foot/group2/subgroup]\n")
+                         _T("subentry=subvalue\n")
+                         _T("subentry2=subvalue2\n")
+                         _T("[foot/group1]\n"),
+                         fc );
+
+    CPPUNIT_ASSERT( fc.RenameGroup(_T("group1"), _T("groupTmp")) );
+    wxVERIFY_FILECONFIG( _T("[foot]\n")
+                         _T("entry=value\n")
+                         _T("[foot/group2]\n")
+                         _T("[foot/group2/subgroup]\n")
+                         _T("subentry=subvalue\n")
+                         _T("subentry2=subvalue2\n")
+                         _T("[foot/groupTmp]\n"),
+                         fc );
+
+    CPPUNIT_ASSERT( fc.RenameGroup(_T("group2"), _T("group1")) );
+    wxVERIFY_FILECONFIG( _T("[foot]\n")
+                         _T("entry=value\n")
+                         _T("[foot/group1]\n")
+                         _T("[foot/group1/subgroup]\n")
+                         _T("subentry=subvalue\n")
+                         _T("subentry2=subvalue2\n")
+                         _T("[foot/groupTmp]\n"),
+                         fc );
+
+    CPPUNIT_ASSERT( fc.RenameGroup(_T("groupTmp"), _T("group2")) );
+    wxVERIFY_FILECONFIG( _T("[foot]\n")
+                         _T("entry=value\n")
+                         _T("[foot/group1]\n")
+                         _T("[foot/group1/subgroup]\n")
+                         _T("subentry=subvalue\n")
+                         _T("subentry2=subvalue2\n")
+                         _T("[foot/group2]\n"),
+                         fc );
+}
+
+void FileConfigTestCase::CreateSubgroupAndEntries()
+{
+    wxFileConfig fc;
+    fc.Write(_T("sub/sub_first"), _T("sub_one"));
+    fc.Write(_T("first"), _T("one"));
+
+    wxVERIFY_FILECONFIG( _T("first=one\n")
+                         _T("[sub]\n")
+                         _T("sub_first=sub_one\n"),
+                         fc );
+}
+
+void FileConfigTestCase::CreateEntriesAndSubgroup()
+{
+    wxFileConfig fc;
+    fc.Write(_T("first"), _T("one"));
+    fc.Write(_T("second"), _T("two"));
+    fc.Write(_T("sub/sub_first"), _T("sub_one"));
+
+    wxVERIFY_FILECONFIG( _T("first=one\n")
+                         _T("second=two\n")
+                         _T("[sub]\n")
+                         _T("sub_first=sub_one\n"),
+                         fc );
+}
+
+static void EmptyConfigAndWriteKey()
+{
+    wxFileConfig fc(_T("deleteconftest"));
+
+    const wxString groupPath = _T("/root");
+
+    if ( fc.Exists(groupPath) )
+    {
+        // using DeleteGroup exposes the problem, using DeleteAll doesn't
+        CPPUNIT_ASSERT( fc.DeleteGroup(groupPath) );
+    }
+
+    // the config must be empty for the problem to arise
+    CPPUNIT_ASSERT( !fc.GetNumberOfEntries(true) );
+    CPPUNIT_ASSERT( !fc.GetNumberOfGroups(true) );
+
+
+    // this crashes on second call of this function
+    CPPUNIT_ASSERT( fc.Write(groupPath + _T("/entry"), _T("value")) );
+}
+
+void FileConfigTestCase::DeleteLastGroup()
+{
+    /*
+    We make 2 of the same calls, first to create a file config with a single
+    group and key...
+    */
+    ::EmptyConfigAndWriteKey();
+
+    /*
+    ... then the same but this time the key's group is deleted before the
+    key is written again. This causes a crash.
+    */
+    ::EmptyConfigAndWriteKey();
+
+
+    // clean up
+    wxLogNull noLogging;
+    (void) ::wxRemoveFile(wxFileConfig::GetLocalFileName(_T("deleteconftest")));
+}
+
+void FileConfigTestCase::DeleteAndRecreateGroup()
+{
+    static const wxChar *confInitial =
+        _T("[First]\n")
+        _T("Value1=Foo\n")
+        _T("[Second]\n")
+        _T("Value2=Bar\n");
+
+    wxStringInputStream sis(confInitial);
+    wxFileConfig fc(sis);
+
+    fc.DeleteGroup(_T("Second"));
+    wxVERIFY_FILECONFIG( _T("[First]\n")
+                         _T("Value1=Foo\n"),
+                         fc );
+
+    fc.Write(_T("Second/Value2"), _T("New"));
+    wxVERIFY_FILECONFIG( _T("[First]\n")
+                         _T("Value1=Foo\n")
+                         _T("[Second]\n")
+                         _T("Value2=New\n"),
+                         fc );
 }
 
 #endif // wxUSE_FILECONFIG