From f5f2db8b44aee02df96f25a765594c519cf581eb Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Mar 2021 16:34:21 +0100 Subject: [PATCH 1/8] Get rid of CppUnit boilerplate in wxConfig unit tests No real changes. --- tests/config/config.cpp | 96 +++++-------- tests/config/fileconf.cpp | 284 ++++++++++++++------------------------ tests/config/regconf.cpp | 49 ++----- 3 files changed, 156 insertions(+), 273 deletions(-) diff --git a/tests/config/config.cpp b/tests/config/config.cpp index 57e9acbbe3..a98e0bbfa1 100644 --- a/tests/config/config.cpp +++ b/tests/config/config.cpp @@ -28,36 +28,10 @@ #include "wx/colour.h" // -------------------------------------------------------------------------- -// test class +// the tests // -------------------------------------------------------------------------- -class ConfigTestCase : public CppUnit::TestCase -{ -public: - ConfigTestCase() {} - -private: - CPPUNIT_TEST_SUITE( ConfigTestCase ); - CPPUNIT_TEST( ReadWriteLocalTest ); - CPPUNIT_TEST( RecordingDefaultsTest ); - CPPUNIT_TEST_SUITE_END(); - - void ReadWriteLocalTest(); - void RecordingDefaultsTest(); - - // return the number of values we (attempted to) read - size_t ReadValues(wxConfig *config, bool has_values); - - wxDECLARE_NO_COPY_CLASS(ConfigTestCase); -}; - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION( ConfigTestCase ); - -// also include in its own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ConfigTestCase, "ConfigTestCase" ); - -void ConfigTestCase::ReadWriteLocalTest() +TEST_CASE("wxConfig::ReadWriteLocal", "[config]") { wxString app = wxT("wxConfigTestCase"); wxString vendor = wxT("wxWidgets"); @@ -79,60 +53,62 @@ void ConfigTestCase::ReadWriteLocalTest() config = new wxConfig(app, vendor, wxT(""), wxT(""), wxCONFIG_USE_LOCAL_FILE); wxString string1 = config->Read(wxT("string1")); - CPPUNIT_ASSERT_EQUAL( "abc", string1 ); + CHECK( string1 == "abc" ); string1 = config->Read(wxT("string1"), wxT("defaultvalue")); - CPPUNIT_ASSERT_EQUAL( "abc", string1 ); + CHECK( string1 == "abc" ); wxString string2; bool r = config->Read(wxT("string2"), &string2); - CPPUNIT_ASSERT( r ); - CPPUNIT_ASSERT_EQUAL( "def", string2 ); + CHECK( r ); + CHECK( string2 == "def" ); r = config->Read(wxT("string2"), &string2, wxT("defaultvalue")); - CPPUNIT_ASSERT( r ); - CPPUNIT_ASSERT_EQUAL( "def", string2 ); + CHECK( r ); + CHECK( string2 == "def" ); int int1 = config->Read(wxT("int1"), 5); - CPPUNIT_ASSERT_EQUAL( 123, int1 ); + CHECK( int1 == 123 ); long long1; r = config->Read(wxT("long1"), &long1); - CPPUNIT_ASSERT( r ); - CPPUNIT_ASSERT_EQUAL( 234L, long1 ); + CHECK( r ); + CHECK( long1 == 234L ); - CPPUNIT_ASSERT( config->ReadLong(wxT("long1"), 0) == 234 ); + CHECK( config->ReadLong(wxT("long1"), 0) == 234 ); double double1; r = config->Read(wxT("double1"), &double1); - CPPUNIT_ASSERT( r ); - CPPUNIT_ASSERT_EQUAL( 345.67, double1 ); + CHECK( r ); + CHECK( double1 == 345.67 ); - CPPUNIT_ASSERT( config->ReadDouble(wxT("double1"), 0) == double1 ); + CHECK( config->ReadDouble(wxT("double1"), 0) == double1 ); bool bool1; r = config->Read(wxT("foo"), &bool1); // there is no "foo" key - CPPUNIT_ASSERT( !r ); + CHECK( !r ); r = config->Read(wxT("bool1"), &bool1); - CPPUNIT_ASSERT( r ); - CPPUNIT_ASSERT_EQUAL( true, bool1 ); + CHECK( r ); + CHECK( bool1 == true ); - CPPUNIT_ASSERT( config->ReadBool(wxT("bool1"), false) == bool1 ); + CHECK( config->ReadBool(wxT("bool1"), false) == bool1 ); #ifdef wxHAS_CONFIG_TEMPLATE_RW wxColour color1; r = config->Read(wxT("color1"), &color1); - CPPUNIT_ASSERT( r ); - CPPUNIT_ASSERT( color1 == wxColour(11,22,33,44) ); + CHECK( r ); + CHECK( color1 == wxColour(11,22,33,44) ); - CPPUNIT_ASSERT( config->ReadObject(wxT("color1"), wxNullColour) == color1 ); + CHECK( config->ReadObject(wxT("color1"), wxNullColour) == color1 ); #endif // wxHAS_CONFIG_TEMPLATE_RW config->DeleteAll(); delete config; } -size_t ConfigTestCase::ReadValues(wxConfig *config, bool has_values) +// Helper of RecordingDefaultsTest() test. +static +size_t ReadValues(wxConfig *config, bool has_values) { size_t read = 0; bool r; @@ -145,42 +121,42 @@ size_t ConfigTestCase::ReadValues(wxConfig *config, bool has_values) wxString string3; r = config->Read(wxT("string3"), &string3, wxT("abc")); - CPPUNIT_ASSERT_EQUAL( has_values, r ); + CHECK( r == has_values ); read++; wxString string4; r = config->Read(wxT("string4"), &string4, wxString(wxT("def"))); - CPPUNIT_ASSERT_EQUAL( has_values, r ); + CHECK( r == has_values ); read++; int int1; r = config->Read(wxT("int1"), &int1, 123); - CPPUNIT_ASSERT_EQUAL( has_values, r ); + CHECK( r == has_values ); read++; int int2 = config->Read(wxT("int2"), 1234); - CPPUNIT_ASSERT_EQUAL( int2, 1234 ); + CHECK( 1234 == int2 ); read++; long long1; r = config->Read(wxString(wxT("long1")), &long1, 234L); - CPPUNIT_ASSERT_EQUAL( has_values, r ); + CHECK( r == has_values ); read++; double double1; r = config->Read(wxT("double1"), &double1, 345.67); - CPPUNIT_ASSERT_EQUAL( has_values, r ); + CHECK( r == has_values ); read++; bool bool1; r = config->Read(wxT("bool1"), &bool1, true); - CPPUNIT_ASSERT_EQUAL( has_values, r ); + CHECK( r == has_values ); read++; #ifdef wxHAS_CONFIG_TEMPLATE_RW wxColour color1; r = config->Read(wxT("color1"), &color1, wxColour(11,22,33,44)); - CPPUNIT_ASSERT_EQUAL( has_values, r ); + CHECK( r == has_values ); read++; #endif // wxHAS_CONFIG_TEMPLATE_RW @@ -188,7 +164,7 @@ size_t ConfigTestCase::ReadValues(wxConfig *config, bool has_values) } -void ConfigTestCase::RecordingDefaultsTest() +TEST_CASE("wxConfig::RecordingDefaults", "[config]") { wxString app = wxT("wxConfigTestCaseRD"); wxString vendor = wxT("wxWidgets"); @@ -197,10 +173,10 @@ void ConfigTestCase::RecordingDefaultsTest() config->DeleteAll(); config->SetRecordDefaults(false); // by default it is false ReadValues(config, false); - CPPUNIT_ASSERT_EQUAL( 0, config->GetNumberOfEntries() ); + CHECK( config->GetNumberOfEntries() == 0 ); config->SetRecordDefaults(true); size_t read = ReadValues(config, false); - CPPUNIT_ASSERT_EQUAL( read, config->GetNumberOfEntries() ); + CHECK( config->GetNumberOfEntries() == read ); ReadValues(config, true); config->DeleteAll(); delete config; diff --git a/tests/config/fileconf.cpp b/tests/config/fileconf.cpp index 019b27ab76..a8752d992c 100644 --- a/tests/config/fileconf.cpp +++ b/tests/config/fileconf.cpp @@ -44,108 +44,33 @@ static wxString Dump(wxFileConfig& fc) } // helper macro to test wxFileConfig contents -#define wxVERIFY_FILECONFIG(t, fc) CPPUNIT_ASSERT_EQUAL(wxString(t), Dump(fc)) +#define wxVERIFY_FILECONFIG(t, fc) CHECK(Dump(fc) == t) + +static wxString ChangePath(wxFileConfig& fc, const wxChar *path) +{ + fc.SetPath(path); + + return fc.GetPath(); +} // ---------------------------------------------------------------------------- // test class // ---------------------------------------------------------------------------- -class FileConfigTestCase : public CppUnit::TestCase -{ -public: - FileConfigTestCase() { } - -private: - CPPUNIT_TEST_SUITE( FileConfigTestCase ); - CPPUNIT_TEST( Path ); - CPPUNIT_TEST( AddEntries ); - CPPUNIT_TEST( GetEntries ); - CPPUNIT_TEST( GetGroups ); - CPPUNIT_TEST( HasEntry ); - CPPUNIT_TEST( HasGroup ); - CPPUNIT_TEST( Binary ); - CPPUNIT_TEST( Save ); - CPPUNIT_TEST( DeleteEntry ); - CPPUNIT_TEST( DeleteAndWriteEntry ); - CPPUNIT_TEST( DeleteLastRootEntry ); - CPPUNIT_TEST( DeleteGroup ); - CPPUNIT_TEST( DeleteAll ); - CPPUNIT_TEST( RenameEntry ); - CPPUNIT_TEST( RenameGroup ); - CPPUNIT_TEST( CreateEntriesAndSubgroup ); - CPPUNIT_TEST( CreateSubgroupAndEntries ); - CPPUNIT_TEST( DeleteLastGroup ); - CPPUNIT_TEST( DeleteAndRecreateGroup ); - CPPUNIT_TEST( AddToExistingRoot ); - CPPUNIT_TEST( ReadNonExistent ); - CPPUNIT_TEST( ReadEmpty ); - CPPUNIT_TEST( ReadFloat ); - CPPUNIT_TEST_SUITE_END(); - - void Path(); - void AddEntries(); - void GetEntries(); - void GetGroups(); - void HasEntry(); - void HasGroup(); - void Binary(); - void Save(); - void DeleteEntry(); - void DeleteAndWriteEntry(); - void DeleteLastRootEntry(); - void DeleteGroup(); - void DeleteAll(); - void RenameEntry(); - void RenameGroup(); - void CreateEntriesAndSubgroup(); - void CreateSubgroupAndEntries(); - void DeleteLastGroup(); - void DeleteAndRecreateGroup(); - void AddToExistingRoot(); - void ReadNonExistent(); - void ReadEmpty(); - void ReadFloat(); - - - static wxString ChangePath(wxFileConfig& fc, const wxChar *path) - { - fc.SetPath(path); - - return fc.GetPath(); - } - - void CheckGroupEntries(const wxFileConfig& fc, - const wxChar *path, - size_t nEntries, - ...); - void CheckGroupSubgroups(const wxFileConfig& fc, - const wxChar *path, - size_t nGroups, - ...); - - wxDECLARE_NO_COPY_CLASS(FileConfigTestCase); -}; - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION( FileConfigTestCase ); - -// also include in its own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileConfigTestCase, "FileConfigTestCase" ); - -void FileConfigTestCase::Path() +TEST_CASE("wxFileConfig::Path", "[fileconfig][config]") { wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CPPUNIT_ASSERT( ChangePath(fc, wxT("")) == wxT("") ); - CPPUNIT_ASSERT( ChangePath(fc, wxT("/")) == wxT("") ); - CPPUNIT_ASSERT( ChangePath(fc, wxT("root")) == wxT("/root") ); - CPPUNIT_ASSERT( ChangePath(fc, wxT("/root")) == wxT("/root") ); - CPPUNIT_ASSERT( ChangePath(fc, wxT("/root/group1/subgroup")) == wxT("/root/group1/subgroup") ); - CPPUNIT_ASSERT( ChangePath(fc, wxT("/root/group2")) == wxT("/root/group2") ); + CHECK( ChangePath(fc, wxT("")) == wxT("") ); + CHECK( ChangePath(fc, wxT("/")) == wxT("") ); + CHECK( ChangePath(fc, wxT("root")) == wxT("/root") ); + CHECK( ChangePath(fc, wxT("/root")) == wxT("/root") ); + CHECK( ChangePath(fc, wxT("/root/group1/subgroup")) == wxT("/root/group1/subgroup") ); + CHECK( ChangePath(fc, wxT("/root/group2")) == wxT("/root/group2") ); } -void FileConfigTestCase::AddEntries() +TEST_CASE("wxFileConfig::AddEntries", "[fileconfig][config]") { wxFileConfig fc; @@ -167,15 +92,18 @@ void FileConfigTestCase::AddEntries() wxVERIFY_FILECONFIG( wxT("Foo=foo\n[Bar]\nBaz=baz\n"), fc ); } +namespace +{ + void -FileConfigTestCase::CheckGroupEntries(const wxFileConfig& fc, - const wxChar *path, - size_t nEntries, - ...) +CheckGroupEntries(const wxFileConfig& fc, + const wxChar *path, + size_t nEntries, + ...) { wxConfigPathChanger change(&fc, wxString(path) + wxT("/")); - CPPUNIT_ASSERT( fc.GetNumberOfEntries() == nEntries ); + CHECK( fc.GetNumberOfEntries() == nEntries ); va_list ap; va_start(ap, nEntries); @@ -186,23 +114,23 @@ FileConfigTestCase::CheckGroupEntries(const wxFileConfig& fc, cont; cont = fc.GetNextEntry(name, cookie), nEntries-- ) { - CPPUNIT_ASSERT( name == va_arg(ap, wxChar *) ); + CHECK( name == va_arg(ap, wxChar *) ); } - CPPUNIT_ASSERT( nEntries == 0 ); + CHECK( nEntries == 0 ); va_end(ap); } void -FileConfigTestCase::CheckGroupSubgroups(const wxFileConfig& fc, - const wxChar *path, - size_t nGroups, - ...) +CheckGroupSubgroups(const wxFileConfig& fc, + const wxChar *path, + size_t nGroups, + ...) { wxConfigPathChanger change(&fc, wxString(path) + wxT("/")); - CPPUNIT_ASSERT( fc.GetNumberOfGroups() == nGroups ); + CHECK( fc.GetNumberOfGroups() == nGroups ); va_list ap; va_start(ap, nGroups); @@ -213,15 +141,17 @@ FileConfigTestCase::CheckGroupSubgroups(const wxFileConfig& fc, cont; cont = fc.GetNextGroup(name, cookie), nGroups-- ) { - CPPUNIT_ASSERT( name == va_arg(ap, wxChar *) ); + CHECK( name == va_arg(ap, wxChar *) ); } - CPPUNIT_ASSERT( nGroups == 0 ); + CHECK( nGroups == 0 ); va_end(ap); } -void FileConfigTestCase::GetEntries() +} // anonymous namespace + +TEST_CASE("wxFileConfig::GetEntries", "[fileconfig][config]") { wxStringInputStream sis(testconfig); wxFileConfig fc(sis); @@ -233,7 +163,7 @@ void FileConfigTestCase::GetEntries() 2, wxT("subentry"), wxT("subentry2")); } -void FileConfigTestCase::GetGroups() +TEST_CASE("wxFileConfig::GetGroups", "[fileconfig][config]") { wxStringInputStream sis(testconfig); wxFileConfig fc(sis); @@ -244,39 +174,39 @@ void FileConfigTestCase::GetGroups() CheckGroupSubgroups(fc, wxT("/root/group2"), 0); } -void FileConfigTestCase::HasEntry() +TEST_CASE("wxFileConfig::HasEntry", "[fileconfig][config]") { wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CPPUNIT_ASSERT( !fc.HasEntry(wxT("root")) ); - CPPUNIT_ASSERT( fc.HasEntry(wxT("root/entry")) ); - CPPUNIT_ASSERT( fc.HasEntry(wxT("/root/entry")) ); - CPPUNIT_ASSERT( fc.HasEntry(wxT("root/group1/subgroup/subentry")) ); - CPPUNIT_ASSERT( !fc.HasEntry(wxT("")) ); - CPPUNIT_ASSERT( !fc.HasEntry(wxT("root/group1")) ); - CPPUNIT_ASSERT( !fc.HasEntry(wxT("subgroup/subentry")) ); - CPPUNIT_ASSERT( !fc.HasEntry(wxT("/root/no_such_group/entry")) ); - CPPUNIT_ASSERT( !fc.HasGroup(wxT("/root/no_such_group")) ); + CHECK( !fc.HasEntry(wxT("root")) ); + CHECK( fc.HasEntry(wxT("root/entry")) ); + CHECK( fc.HasEntry(wxT("/root/entry")) ); + CHECK( fc.HasEntry(wxT("root/group1/subgroup/subentry")) ); + CHECK( !fc.HasEntry(wxT("")) ); + CHECK( !fc.HasEntry(wxT("root/group1")) ); + CHECK( !fc.HasEntry(wxT("subgroup/subentry")) ); + CHECK( !fc.HasEntry(wxT("/root/no_such_group/entry")) ); + CHECK( !fc.HasGroup(wxT("/root/no_such_group")) ); } -void FileConfigTestCase::HasGroup() +TEST_CASE("wxFileConfig::HasGroup", "[fileconfig][config]") { wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CPPUNIT_ASSERT( fc.HasGroup(wxT("root")) ); - CPPUNIT_ASSERT( fc.HasGroup(wxT("root/group1")) ); - CPPUNIT_ASSERT( fc.HasGroup(wxT("root/group1/subgroup")) ); - CPPUNIT_ASSERT( fc.HasGroup(wxT("root/group2")) ); - CPPUNIT_ASSERT( !fc.HasGroup(wxT("")) ); - CPPUNIT_ASSERT( !fc.HasGroup(wxT("root/group")) ); - CPPUNIT_ASSERT( !fc.HasGroup(wxT("root//subgroup")) ); - CPPUNIT_ASSERT( !fc.HasGroup(wxT("foot/subgroup")) ); - CPPUNIT_ASSERT( !fc.HasGroup(wxT("foot")) ); + CHECK( fc.HasGroup(wxT("root")) ); + CHECK( fc.HasGroup(wxT("root/group1")) ); + CHECK( fc.HasGroup(wxT("root/group1/subgroup")) ); + CHECK( fc.HasGroup(wxT("root/group2")) ); + CHECK( !fc.HasGroup(wxT("")) ); + CHECK( !fc.HasGroup(wxT("root/group")) ); + CHECK( !fc.HasGroup(wxT("root//subgroup")) ); + CHECK( !fc.HasGroup(wxT("foot/subgroup")) ); + CHECK( !fc.HasGroup(wxT("foot")) ); } -void FileConfigTestCase::Binary() +TEST_CASE("wxFileConfig::Binary", "[fileconfig][config]") { wxStringInputStream sis( "[root]\n" @@ -287,7 +217,7 @@ void FileConfigTestCase::Binary() wxMemoryBuffer buf; fc.Read("/root/binary", &buf); - CPPUNIT_ASSERT( memcmp("foo\n", buf.GetData(), buf.GetDataLen()) == 0 ); + CHECK( memcmp("foo\n", buf.GetData(), buf.GetDataLen()) == 0 ); buf.SetDataLen(0); buf.AppendData("\0\1\2", 3); @@ -300,21 +230,21 @@ void FileConfigTestCase::Binary() ); } -void FileConfigTestCase::Save() +TEST_CASE("wxFileConfig::Save", "[fileconfig][config]") { wxStringInputStream sis(testconfig); wxFileConfig fc(sis); wxVERIFY_FILECONFIG( testconfig, fc ); } -void FileConfigTestCase::DeleteEntry() +TEST_CASE("wxFileConfig::DeleteEntry", "[fileconfig][config]") { wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CPPUNIT_ASSERT( !fc.DeleteEntry(wxT("foo")) ); + CHECK( !fc.DeleteEntry(wxT("foo")) ); - CPPUNIT_ASSERT( fc.DeleteEntry(wxT("root/group1/subgroup/subentry")) ); + CHECK( fc.DeleteEntry(wxT("root/group1/subgroup/subentry")) ); wxVERIFY_FILECONFIG( wxT("[root]\n") wxT("entry=value\n") wxT("[root/group1]\n") @@ -325,7 +255,7 @@ void FileConfigTestCase::DeleteEntry() // group should be deleted now as well as it became empty wxConfigPathChanger change(&fc, wxT("root/group1/subgroup/subentry2")); - CPPUNIT_ASSERT( fc.DeleteEntry(wxT("subentry2")) ); + CHECK( fc.DeleteEntry(wxT("subentry2")) ); wxVERIFY_FILECONFIG( wxT("[root]\n") wxT("entry=value\n") wxT("[root/group1]\n") @@ -333,7 +263,7 @@ void FileConfigTestCase::DeleteEntry() fc ); } -void FileConfigTestCase::DeleteAndWriteEntry() +TEST_CASE("wxFileConfig::DeleteAndWriteEntry", "[fileconfig][config]") { wxStringInputStream sis( "[root/group1]\n" @@ -374,7 +304,7 @@ void FileConfigTestCase::DeleteAndWriteEntry() wxVERIFY_FILECONFIG( "", fc ); } -void FileConfigTestCase::DeleteLastRootEntry() +TEST_CASE("wxFileConfig::DeleteLastRootEntry", "[fileconfig][config]") { // This tests for the bug which occurred when the last entry of the root // group was deleted: this corrupted internal state and resulted in a crash @@ -392,45 +322,45 @@ void FileConfigTestCase::DeleteLastRootEntry() wxVERIFY_FILECONFIG( "key=value\n", fc ); } -void FileConfigTestCase::DeleteGroup() +TEST_CASE("wxFileConfig::DeleteGroup", "[fileconfig][config]") { wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CPPUNIT_ASSERT( !fc.DeleteGroup(wxT("foo")) ); + CHECK( !fc.DeleteGroup(wxT("foo")) ); - CPPUNIT_ASSERT( fc.DeleteGroup(wxT("root/group1")) ); + CHECK( fc.DeleteGroup(wxT("root/group1")) ); wxVERIFY_FILECONFIG( wxT("[root]\n") wxT("entry=value\n") wxT("[root/group2]\n"), fc ); // notice trailing slash: it should be ignored - CPPUNIT_ASSERT( fc.DeleteGroup(wxT("root/group2/")) ); + CHECK( fc.DeleteGroup(wxT("root/group2/")) ); wxVERIFY_FILECONFIG( wxT("[root]\n") wxT("entry=value\n"), fc ); - CPPUNIT_ASSERT( fc.DeleteGroup(wxT("root")) ); - CPPUNIT_ASSERT( Dump(fc).empty() ); + CHECK( fc.DeleteGroup(wxT("root")) ); + CHECK( Dump(fc).empty() ); } -void FileConfigTestCase::DeleteAll() +TEST_CASE("wxFileConfig::DeleteAll", "[fileconfig][config]") { wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CPPUNIT_ASSERT( fc.DeleteAll() ); - CPPUNIT_ASSERT( Dump(fc).empty() ); + CHECK( fc.DeleteAll() ); + CHECK( Dump(fc).empty() ); } -void FileConfigTestCase::RenameEntry() +TEST_CASE("wxFileConfig::RenameEntry", "[fileconfig][config]") { wxStringInputStream sis(testconfig); wxFileConfig fc(sis); fc.SetPath(wxT("root")); - CPPUNIT_ASSERT( fc.RenameEntry(wxT("entry"), wxT("newname")) ); + CHECK( fc.RenameEntry(wxT("entry"), wxT("newname")) ); wxVERIFY_FILECONFIG( wxT("[root]\n") wxT("newname=value\n") wxT("[root/group1]\n") @@ -441,10 +371,10 @@ void FileConfigTestCase::RenameEntry() fc ); fc.SetPath(wxT("group1/subgroup")); - CPPUNIT_ASSERT( !fc.RenameEntry(wxT("entry"), wxT("newname")) ); - CPPUNIT_ASSERT( !fc.RenameEntry(wxT("subentry"), wxT("subentry2")) ); + CHECK( !fc.RenameEntry(wxT("entry"), wxT("newname")) ); + CHECK( !fc.RenameEntry(wxT("subentry"), wxT("subentry2")) ); - CPPUNIT_ASSERT( fc.RenameEntry(wxT("subentry"), wxT("subentry1")) ); + CHECK( fc.RenameEntry(wxT("subentry"), wxT("subentry1")) ); wxVERIFY_FILECONFIG( wxT("[root]\n") wxT("newname=value\n") wxT("[root/group1]\n") @@ -455,12 +385,12 @@ void FileConfigTestCase::RenameEntry() fc ); } -void FileConfigTestCase::RenameGroup() +TEST_CASE("wxFileConfig::RenameGroup", "[fileconfig][config]") { wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CPPUNIT_ASSERT( fc.RenameGroup(wxT("root"), wxT("foot")) ); + CHECK( fc.RenameGroup(wxT("root"), wxT("foot")) ); wxVERIFY_FILECONFIG( wxT("[foot]\n") wxT("entry=value\n") wxT("[foot/group1]\n") @@ -471,16 +401,16 @@ void FileConfigTestCase::RenameGroup() fc ); // renaming a path doesn't work, it must be the immediate group - CPPUNIT_ASSERT( !fc.RenameGroup(wxT("foot/group1"), wxT("group2")) ); + CHECK( !fc.RenameGroup(wxT("foot/group1"), wxT("group2")) ); fc.SetPath(wxT("foot")); // renaming to a name of existing group doesn't work - CPPUNIT_ASSERT( !fc.RenameGroup(wxT("group1"), wxT("group2")) ); + CHECK( !fc.RenameGroup(wxT("group1"), wxT("group2")) ); // try exchanging the groups names and then restore them back - CPPUNIT_ASSERT( fc.RenameGroup(wxT("group1"), wxT("groupTmp")) ); + CHECK( fc.RenameGroup(wxT("group1"), wxT("groupTmp")) ); wxVERIFY_FILECONFIG( wxT("[foot]\n") wxT("entry=value\n") wxT("[foot/groupTmp]\n") @@ -490,7 +420,7 @@ void FileConfigTestCase::RenameGroup() wxT("[foot/group2]\n"), fc ); - CPPUNIT_ASSERT( fc.RenameGroup(wxT("group2"), wxT("group1")) ); + CHECK( fc.RenameGroup(wxT("group2"), wxT("group1")) ); wxVERIFY_FILECONFIG( wxT("[foot]\n") wxT("entry=value\n") wxT("[foot/groupTmp]\n") @@ -500,7 +430,7 @@ void FileConfigTestCase::RenameGroup() wxT("[foot/group1]\n"), fc ); - CPPUNIT_ASSERT( fc.RenameGroup(wxT("groupTmp"), wxT("group2")) ); + CHECK( fc.RenameGroup(wxT("groupTmp"), wxT("group2")) ); wxVERIFY_FILECONFIG( wxT("[foot]\n") wxT("entry=value\n") wxT("[foot/group2]\n") @@ -510,7 +440,7 @@ void FileConfigTestCase::RenameGroup() wxT("[foot/group1]\n"), fc ); - CPPUNIT_ASSERT( fc.RenameGroup(wxT("group1"), wxT("groupTmp")) ); + CHECK( fc.RenameGroup(wxT("group1"), wxT("groupTmp")) ); wxVERIFY_FILECONFIG( wxT("[foot]\n") wxT("entry=value\n") wxT("[foot/group2]\n") @@ -520,7 +450,7 @@ void FileConfigTestCase::RenameGroup() wxT("[foot/groupTmp]\n"), fc ); - CPPUNIT_ASSERT( fc.RenameGroup(wxT("group2"), wxT("group1")) ); + CHECK( fc.RenameGroup(wxT("group2"), wxT("group1")) ); wxVERIFY_FILECONFIG( wxT("[foot]\n") wxT("entry=value\n") wxT("[foot/group1]\n") @@ -530,7 +460,7 @@ void FileConfigTestCase::RenameGroup() wxT("[foot/groupTmp]\n"), fc ); - CPPUNIT_ASSERT( fc.RenameGroup(wxT("groupTmp"), wxT("group2")) ); + CHECK( fc.RenameGroup(wxT("groupTmp"), wxT("group2")) ); wxVERIFY_FILECONFIG( wxT("[foot]\n") wxT("entry=value\n") wxT("[foot/group1]\n") @@ -541,7 +471,7 @@ void FileConfigTestCase::RenameGroup() fc ); } -void FileConfigTestCase::CreateSubgroupAndEntries() +TEST_CASE("wxFileConfig::CreateSubgroupAndEntries", "[fileconfig][config]") { wxFileConfig fc; fc.Write(wxT("sub/sub_first"), wxT("sub_one")); @@ -553,7 +483,7 @@ void FileConfigTestCase::CreateSubgroupAndEntries() fc ); } -void FileConfigTestCase::CreateEntriesAndSubgroup() +TEST_CASE("wxFileConfig::CreateEntriesAndSubgroup", "[fileconfig][config]") { wxFileConfig fc; fc.Write(wxT("first"), wxT("one")); @@ -576,19 +506,19 @@ static void EmptyConfigAndWriteKey() if ( fc.Exists(groupPath) ) { // using DeleteGroup exposes the problem, using DeleteAll doesn't - CPPUNIT_ASSERT( fc.DeleteGroup(groupPath) ); + CHECK( fc.DeleteGroup(groupPath) ); } // the config must be empty for the problem to arise - CPPUNIT_ASSERT( !fc.GetNumberOfEntries(true) ); - CPPUNIT_ASSERT( !fc.GetNumberOfGroups(true) ); + CHECK( !fc.GetNumberOfEntries(true) ); + CHECK( !fc.GetNumberOfGroups(true) ); // this crashes on second call of this function - CPPUNIT_ASSERT( fc.Write(groupPath + wxT("/entry"), wxT("value")) ); + CHECK( fc.Write(groupPath + wxT("/entry"), wxT("value")) ); } -void FileConfigTestCase::DeleteLastGroup() +TEST_CASE("wxFileConfig::DeleteLastGroup", "[fileconfig][config]") { /* We make 2 of the same calls, first to create a file config with a single @@ -608,7 +538,7 @@ void FileConfigTestCase::DeleteLastGroup() (void) ::wxRemoveFile(wxFileConfig::GetLocalFileName(wxT("deleteconftest"))); } -void FileConfigTestCase::DeleteAndRecreateGroup() +TEST_CASE("wxFileConfig::DeleteAndRecreateGroup", "[fileconfig][config]") { static const wxChar *confInitial = wxT("[First]\n") @@ -632,7 +562,7 @@ void FileConfigTestCase::DeleteAndRecreateGroup() fc ); } -void FileConfigTestCase::AddToExistingRoot() +TEST_CASE("wxFileConfig::AddToExistingRoot", "[fileconfig][config]") { static const wxChar *confInitial = wxT("[Group]\n") @@ -650,7 +580,7 @@ void FileConfigTestCase::AddToExistingRoot() ); } -void FileConfigTestCase::ReadNonExistent() +TEST_CASE("wxFileConfig::ReadNonExistent", "[fileconfig][config]") { static const char *confTest = "community=censored\n" @@ -666,10 +596,10 @@ void FileConfigTestCase::ReadNonExistent() wxFileConfig fc(sis); wxString url; - CPPUNIT_ASSERT( !fc.Read("URL", &url) ); + CHECK( !fc.Read("URL", &url) ); } -void FileConfigTestCase::ReadEmpty() +TEST_CASE("wxFileConfig::ReadEmpty", "[fileconfig][config]") { static const char *confTest = ""; @@ -677,7 +607,7 @@ void FileConfigTestCase::ReadEmpty() wxFileConfig fc(sis); } -void FileConfigTestCase::ReadFloat() +TEST_CASE("wxFileConfig::ReadFloat", "[fileconfig][config]") { static const char *confTest = "x=1.234\n" @@ -689,11 +619,11 @@ void FileConfigTestCase::ReadFloat() wxFileConfig fc(sis); float f; - CPPUNIT_ASSERT( fc.Read("x", &f) ); - CPPUNIT_ASSERT_EQUAL( 1.234f, f ); + CHECK( fc.Read("x", &f) ); + CHECK( f == 1.234f ); - CPPUNIT_ASSERT( fc.Read("y", &f) ); - CPPUNIT_ASSERT_EQUAL( -9876.5432f, f ); + CHECK( fc.Read("y", &f) ); + CHECK( f == -9876.5432f ); } #endif // wxUSE_FILECONFIG diff --git a/tests/config/regconf.cpp b/tests/config/regconf.cpp index 339db09516..8e1b0f37a5 100644 --- a/tests/config/regconf.cpp +++ b/tests/config/regconf.cpp @@ -24,30 +24,7 @@ // test class // ---------------------------------------------------------------------------- -class RegConfigTestCase : public CppUnit::TestCase -{ -public: - RegConfigTestCase() { } - -private: - CPPUNIT_TEST_SUITE( RegConfigTestCase ); - CPPUNIT_TEST( ReadWrite ); - CPPUNIT_TEST( DeleteRegistryKeyFromRedirectedView ); - CPPUNIT_TEST_SUITE_END(); - - void ReadWrite(); - void DeleteRegistryKeyFromRedirectedView(); - - wxDECLARE_NO_COPY_CLASS(RegConfigTestCase); -}; - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION( RegConfigTestCase ); - -// also include in its own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( RegConfigTestCase, "RegConfigTestCase" ); - -void RegConfigTestCase::ReadWrite() +TEST_CASE("wxRegConfig::ReadWrite", "[regconfig][config][registry]") { wxString app = wxT("wxRegConfigTestCase"); wxString vendor = wxT("wxWidgets"); @@ -59,27 +36,27 @@ void RegConfigTestCase::ReadWrite() // test writing config->SetPath(wxT("/group1")); - CPPUNIT_ASSERT( config->Write(wxT("entry1"), wxT("foo")) ); + CHECK( config->Write(wxT("entry1"), wxT("foo")) ); config->SetPath(wxT("/group2")); - CPPUNIT_ASSERT( config->Write(wxT("entry1"), wxT("bar")) ); + CHECK( config->Write(wxT("entry1"), wxT("bar")) ); // test reading wxString str; long dummy; config->SetPath(wxT("/")); - CPPUNIT_ASSERT( config->GetFirstGroup(str, dummy) ); - CPPUNIT_ASSERT( str == "group1" ); - CPPUNIT_ASSERT( config->Read(wxT("group1/entry1"), wxT("INVALID DEFAULT")) == "foo" ); - CPPUNIT_ASSERT( config->GetNextGroup(str, dummy) ); - CPPUNIT_ASSERT( str == "group2" ); - CPPUNIT_ASSERT( config->Read(wxT("group2/entry1"), wxT("INVALID DEFAULT")) == "bar" ); + CHECK( config->GetFirstGroup(str, dummy) ); + CHECK( str == "group1" ); + CHECK( config->Read(wxT("group1/entry1"), wxT("INVALID DEFAULT")) == "foo" ); + CHECK( config->GetNextGroup(str, dummy) ); + CHECK( str == "group2" ); + CHECK( config->Read(wxT("group2/entry1"), wxT("INVALID DEFAULT")) == "bar" ); config->DeleteAll(); delete config; } -void RegConfigTestCase::DeleteRegistryKeyFromRedirectedView() +TEST_CASE("wxRegKey::DeleteFromRedirectedView", "[registry][64bits]") { if ( !wxIsPlatform64Bit() ) { @@ -94,9 +71,9 @@ void RegConfigTestCase::DeleteRegistryKeyFromRedirectedView() ? wxRegKey::WOW64ViewMode_64 : wxRegKey::WOW64ViewMode_32); - CPPUNIT_ASSERT( key.Create() ); - CPPUNIT_ASSERT( key.DeleteSelf() ); - CPPUNIT_ASSERT( !key.Exists() ); + REQUIRE( key.Create() ); + CHECK( key.DeleteSelf() ); + CHECK( !key.Exists() ); } #endif // wxUSE_CONFIG && wxUSE_REGKEY From 2e6bb341b795d13058701cf809dea2d92ffea9b0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Mar 2021 17:00:23 +0100 Subject: [PATCH 2/8] Use smart pointer instead of manual delete in wxConfig tests No real changes. --- tests/config/config.cpp | 44 +++++++++++++++++++--------------------- tests/config/regconf.cpp | 7 ++++--- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/tests/config/config.cpp b/tests/config/config.cpp index a98e0bbfa1..101409c5dd 100644 --- a/tests/config/config.cpp +++ b/tests/config/config.cpp @@ -26,6 +26,7 @@ #include "wx/config.h" #include "wx/colour.h" +#include "wx/scopedptr.h" // -------------------------------------------------------------------------- // the tests @@ -35,8 +36,8 @@ TEST_CASE("wxConfig::ReadWriteLocal", "[config]") { wxString app = wxT("wxConfigTestCase"); wxString vendor = wxT("wxWidgets"); - wxConfig *config = new wxConfig(app, vendor, wxT(""), wxT(""), - wxCONFIG_USE_LOCAL_FILE); + wxScopedPtr config(new wxConfig(app, vendor, wxT(""), wxT(""), + wxCONFIG_USE_LOCAL_FILE)); config->DeleteAll(); config->Write(wxT("string1"), wxT("abc")); config->Write(wxT("string2"), wxString(wxT("def"))); @@ -48,10 +49,9 @@ TEST_CASE("wxConfig::ReadWriteLocal", "[config]") config->Write(wxT("color1"), wxColour(11,22,33,44)); #endif // wxHAS_CONFIG_TEMPLATE_RW config->Flush(); - delete config; - config = new wxConfig(app, vendor, wxT(""), wxT(""), - wxCONFIG_USE_LOCAL_FILE); + config.reset(new wxConfig(app, vendor, wxT(""), wxT(""), + wxCONFIG_USE_LOCAL_FILE)); wxString string1 = config->Read(wxT("string1")); CHECK( string1 == "abc" ); string1 = config->Read(wxT("string1"), wxT("defaultvalue")); @@ -103,59 +103,58 @@ TEST_CASE("wxConfig::ReadWriteLocal", "[config]") #endif // wxHAS_CONFIG_TEMPLATE_RW config->DeleteAll(); - delete config; } // Helper of RecordingDefaultsTest() test. static -size_t ReadValues(wxConfig *config, bool has_values) +size_t ReadValues(const wxConfig& config, bool has_values) { size_t read = 0; bool r; - wxString string1 = config->Read(wxT("string1"), wxT("abc")); + wxString string1 = config.Read(wxT("string1"), wxT("abc")); read++; - wxString string2 = config->Read(wxT("string2"), wxString(wxT("def"))); + wxString string2 = config.Read(wxT("string2"), wxString(wxT("def"))); read++; wxString string3; - r = config->Read(wxT("string3"), &string3, wxT("abc")); + r = config.Read(wxT("string3"), &string3, wxT("abc")); CHECK( r == has_values ); read++; wxString string4; - r = config->Read(wxT("string4"), &string4, wxString(wxT("def"))); + r = config.Read(wxT("string4"), &string4, wxString(wxT("def"))); CHECK( r == has_values ); read++; int int1; - r = config->Read(wxT("int1"), &int1, 123); + r = config.Read(wxT("int1"), &int1, 123); CHECK( r == has_values ); read++; - int int2 = config->Read(wxT("int2"), 1234); + int int2 = config.Read(wxT("int2"), 1234); CHECK( 1234 == int2 ); read++; long long1; - r = config->Read(wxString(wxT("long1")), &long1, 234L); + r = config.Read(wxString(wxT("long1")), &long1, 234L); CHECK( r == has_values ); read++; double double1; - r = config->Read(wxT("double1"), &double1, 345.67); + r = config.Read(wxT("double1"), &double1, 345.67); CHECK( r == has_values ); read++; bool bool1; - r = config->Read(wxT("bool1"), &bool1, true); + r = config.Read(wxT("bool1"), &bool1, true); CHECK( r == has_values ); read++; #ifdef wxHAS_CONFIG_TEMPLATE_RW wxColour color1; - r = config->Read(wxT("color1"), &color1, wxColour(11,22,33,44)); + r = config.Read(wxT("color1"), &color1, wxColour(11,22,33,44)); CHECK( r == has_values ); read++; #endif // wxHAS_CONFIG_TEMPLATE_RW @@ -168,18 +167,17 @@ TEST_CASE("wxConfig::RecordingDefaults", "[config]") { wxString app = wxT("wxConfigTestCaseRD"); wxString vendor = wxT("wxWidgets"); - wxConfig *config = new wxConfig(app, vendor, wxT(""), wxT(""), - wxCONFIG_USE_LOCAL_FILE); + wxScopedPtr config(new wxConfig(app, vendor, wxT(""), wxT(""), + wxCONFIG_USE_LOCAL_FILE)); config->DeleteAll(); config->SetRecordDefaults(false); // by default it is false - ReadValues(config, false); + ReadValues(*config, false); CHECK( config->GetNumberOfEntries() == 0 ); config->SetRecordDefaults(true); - size_t read = ReadValues(config, false); + size_t read = ReadValues(*config, false); CHECK( config->GetNumberOfEntries() == read ); - ReadValues(config, true); + ReadValues(*config, true); config->DeleteAll(); - delete config; } #endif //wxUSE_CONFIG diff --git a/tests/config/regconf.cpp b/tests/config/regconf.cpp index 8e1b0f37a5..052a58444a 100644 --- a/tests/config/regconf.cpp +++ b/tests/config/regconf.cpp @@ -20,6 +20,8 @@ #include "wx/msw/regconf.h" +#include "wx/scopedptr.h" + // ---------------------------------------------------------------------------- // test class // ---------------------------------------------------------------------------- @@ -31,8 +33,8 @@ TEST_CASE("wxRegConfig::ReadWrite", "[regconfig][config][registry]") // NOTE: we use wxCONFIG_USE_LOCAL_FILE explicitly to test wxRegConfig // with something different from the default value wxCONFIG_USE_GLOBAL_FILE - wxConfigBase *config = new wxRegConfig(app, vendor, wxT(""), wxT(""), - wxCONFIG_USE_LOCAL_FILE); + wxScopedPtr config(new wxRegConfig(app, vendor, wxT(""), wxT(""), + wxCONFIG_USE_LOCAL_FILE)); // test writing config->SetPath(wxT("/group1")); @@ -53,7 +55,6 @@ TEST_CASE("wxRegConfig::ReadWrite", "[regconfig][config][registry]") CHECK( config->Read(wxT("group2/entry1"), wxT("INVALID DEFAULT")) == "bar" ); config->DeleteAll(); - delete config; } TEST_CASE("wxRegKey::DeleteFromRedirectedView", "[registry][64bits]") From 62cfa638c008ec6c52c4a8cde544a06a5870881c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Mar 2021 17:02:12 +0100 Subject: [PATCH 3/8] Remove wxT() from wxConfig unit tests Just remove the visual noise, no real changes. --- tests/config/config.cpp | 76 ++++---- tests/config/fileconf.cpp | 392 +++++++++++++++++++------------------- tests/config/regconf.cpp | 20 +- 3 files changed, 244 insertions(+), 244 deletions(-) diff --git a/tests/config/config.cpp b/tests/config/config.cpp index 101409c5dd..c7f12ba2b0 100644 --- a/tests/config/config.cpp +++ b/tests/config/config.cpp @@ -34,72 +34,72 @@ TEST_CASE("wxConfig::ReadWriteLocal", "[config]") { - wxString app = wxT("wxConfigTestCase"); - wxString vendor = wxT("wxWidgets"); - wxScopedPtr config(new wxConfig(app, vendor, wxT(""), wxT(""), + wxString app = "wxConfigTestCase"; + wxString vendor = "wxWidgets"; + wxScopedPtr config(new wxConfig(app, vendor, "", "", wxCONFIG_USE_LOCAL_FILE)); config->DeleteAll(); - config->Write(wxT("string1"), wxT("abc")); - config->Write(wxT("string2"), wxString(wxT("def"))); - config->Write(wxT("int1"), 123); - config->Write(wxString(wxT("long1")), 234L); - config->Write(wxT("double1"), 345.67); - config->Write(wxT("bool1"), true); + config->Write("string1", "abc"); + config->Write("string2", wxString("def")); + config->Write("int1", 123); + config->Write(wxString("long1"), 234L); + config->Write("double1", 345.67); + config->Write("bool1", true); #ifdef wxHAS_CONFIG_TEMPLATE_RW - config->Write(wxT("color1"), wxColour(11,22,33,44)); + config->Write("color1", wxColour(11,22,33,44)); #endif // wxHAS_CONFIG_TEMPLATE_RW config->Flush(); - config.reset(new wxConfig(app, vendor, wxT(""), wxT(""), + config.reset(new wxConfig(app, vendor, "", "", wxCONFIG_USE_LOCAL_FILE)); - wxString string1 = config->Read(wxT("string1")); + wxString string1 = config->Read("string1"); CHECK( string1 == "abc" ); - string1 = config->Read(wxT("string1"), wxT("defaultvalue")); + string1 = config->Read("string1", "defaultvalue"); CHECK( string1 == "abc" ); wxString string2; - bool r = config->Read(wxT("string2"), &string2); + bool r = config->Read("string2", &string2); CHECK( r ); CHECK( string2 == "def" ); - r = config->Read(wxT("string2"), &string2, wxT("defaultvalue")); + r = config->Read("string2", &string2, "defaultvalue"); CHECK( r ); CHECK( string2 == "def" ); - int int1 = config->Read(wxT("int1"), 5); + int int1 = config->Read("int1", 5); CHECK( int1 == 123 ); long long1; - r = config->Read(wxT("long1"), &long1); + r = config->Read("long1", &long1); CHECK( r ); CHECK( long1 == 234L ); - CHECK( config->ReadLong(wxT("long1"), 0) == 234 ); + CHECK( config->ReadLong("long1", 0) == 234 ); double double1; - r = config->Read(wxT("double1"), &double1); + r = config->Read("double1", &double1); CHECK( r ); CHECK( double1 == 345.67 ); - CHECK( config->ReadDouble(wxT("double1"), 0) == double1 ); + CHECK( config->ReadDouble("double1", 0) == double1 ); bool bool1; - r = config->Read(wxT("foo"), &bool1); // there is no "foo" key + r = config->Read("foo", &bool1); // there is no "foo" key CHECK( !r ); - r = config->Read(wxT("bool1"), &bool1); + r = config->Read("bool1", &bool1); CHECK( r ); CHECK( bool1 == true ); - CHECK( config->ReadBool(wxT("bool1"), false) == bool1 ); + CHECK( config->ReadBool("bool1", false) == bool1 ); #ifdef wxHAS_CONFIG_TEMPLATE_RW wxColour color1; - r = config->Read(wxT("color1"), &color1); + r = config->Read("color1", &color1); CHECK( r ); CHECK( color1 == wxColour(11,22,33,44) ); - CHECK( config->ReadObject(wxT("color1"), wxNullColour) == color1 ); + CHECK( config->ReadObject("color1", wxNullColour) == color1 ); #endif // wxHAS_CONFIG_TEMPLATE_RW config->DeleteAll(); @@ -112,49 +112,49 @@ size_t ReadValues(const wxConfig& config, bool has_values) size_t read = 0; bool r; - wxString string1 = config.Read(wxT("string1"), wxT("abc")); + wxString string1 = config.Read("string1", "abc"); read++; - wxString string2 = config.Read(wxT("string2"), wxString(wxT("def"))); + wxString string2 = config.Read("string2", wxString("def")); read++; wxString string3; - r = config.Read(wxT("string3"), &string3, wxT("abc")); + r = config.Read("string3", &string3, "abc"); CHECK( r == has_values ); read++; wxString string4; - r = config.Read(wxT("string4"), &string4, wxString(wxT("def"))); + r = config.Read("string4", &string4, wxString("def")); CHECK( r == has_values ); read++; int int1; - r = config.Read(wxT("int1"), &int1, 123); + r = config.Read("int1", &int1, 123); CHECK( r == has_values ); read++; - int int2 = config.Read(wxT("int2"), 1234); + int int2 = config.Read("int2", 1234); CHECK( 1234 == int2 ); read++; long long1; - r = config.Read(wxString(wxT("long1")), &long1, 234L); + r = config.Read(wxString("long1"), &long1, 234L); CHECK( r == has_values ); read++; double double1; - r = config.Read(wxT("double1"), &double1, 345.67); + r = config.Read("double1", &double1, 345.67); CHECK( r == has_values ); read++; bool bool1; - r = config.Read(wxT("bool1"), &bool1, true); + r = config.Read("bool1", &bool1, true); CHECK( r == has_values ); read++; #ifdef wxHAS_CONFIG_TEMPLATE_RW wxColour color1; - r = config.Read(wxT("color1"), &color1, wxColour(11,22,33,44)); + r = config.Read("color1", &color1, wxColour(11,22,33,44)); CHECK( r == has_values ); read++; #endif // wxHAS_CONFIG_TEMPLATE_RW @@ -165,9 +165,9 @@ size_t ReadValues(const wxConfig& config, bool has_values) TEST_CASE("wxConfig::RecordingDefaults", "[config]") { - wxString app = wxT("wxConfigTestCaseRD"); - wxString vendor = wxT("wxWidgets"); - wxScopedPtr config(new wxConfig(app, vendor, wxT(""), wxT(""), + wxString app = "wxConfigTestCaseRD"; + wxString vendor = "wxWidgets"; + wxScopedPtr config(new wxConfig(app, vendor, "", "", wxCONFIG_USE_LOCAL_FILE)); config->DeleteAll(); config->SetRecordDefaults(false); // by default it is false diff --git a/tests/config/fileconf.cpp b/tests/config/fileconf.cpp index a8752d992c..0d64f3a114 100644 --- a/tests/config/fileconf.cpp +++ b/tests/config/fileconf.cpp @@ -22,14 +22,14 @@ #include "wx/sstream.h" #include "wx/log.h" -static const wxChar *testconfig = -wxT("[root]\n") -wxT("entry=value\n") -wxT("[root/group1]\n") -wxT("[root/group1/subgroup]\n") -wxT("subentry=subvalue\n") -wxT("subentry2=subvalue2\n") -wxT("[root/group2]\n") +static const char *testconfig = +"[root]\n" +"entry=value\n" +"[root/group1]\n" +"[root/group1/subgroup]\n" +"subentry=subvalue\n" +"subentry2=subvalue2\n" +"[root/group2]\n" ; // ---------------------------------------------------------------------------- @@ -46,7 +46,7 @@ static wxString Dump(wxFileConfig& fc) // helper macro to test wxFileConfig contents #define wxVERIFY_FILECONFIG(t, fc) CHECK(Dump(fc) == t) -static wxString ChangePath(wxFileConfig& fc, const wxChar *path) +static wxString ChangePath(wxFileConfig& fc, const char *path) { fc.SetPath(path); @@ -62,34 +62,34 @@ TEST_CASE("wxFileConfig::Path", "[fileconfig][config]") wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CHECK( ChangePath(fc, wxT("")) == wxT("") ); - CHECK( ChangePath(fc, wxT("/")) == wxT("") ); - CHECK( ChangePath(fc, wxT("root")) == wxT("/root") ); - CHECK( ChangePath(fc, wxT("/root")) == wxT("/root") ); - CHECK( ChangePath(fc, wxT("/root/group1/subgroup")) == wxT("/root/group1/subgroup") ); - CHECK( ChangePath(fc, wxT("/root/group2")) == wxT("/root/group2") ); + CHECK( ChangePath(fc, "") == "" ); + CHECK( ChangePath(fc, "/") == "" ); + CHECK( ChangePath(fc, "root") == "/root" ); + CHECK( ChangePath(fc, "/root") == "/root" ); + CHECK( ChangePath(fc, "/root/group1/subgroup") == "/root/group1/subgroup" ); + CHECK( ChangePath(fc, "/root/group2") == "/root/group2" ); } TEST_CASE("wxFileConfig::AddEntries", "[fileconfig][config]") { wxFileConfig fc; - wxVERIFY_FILECONFIG( wxT(""), fc ); + wxVERIFY_FILECONFIG( "", fc ); - fc.Write(wxT("/Foo"), wxT("foo")); - wxVERIFY_FILECONFIG( wxT("Foo=foo\n"), fc ); + fc.Write("/Foo", "foo"); + wxVERIFY_FILECONFIG( "Foo=foo\n", fc ); - fc.Write(wxT("/Bar/Baz"), wxT("baz")); - wxVERIFY_FILECONFIG( wxT("Foo=foo\n[Bar]\nBaz=baz\n"), fc ); + fc.Write("/Bar/Baz", "baz"); + wxVERIFY_FILECONFIG( "Foo=foo\n[Bar]\nBaz=baz\n", fc ); fc.DeleteAll(); - wxVERIFY_FILECONFIG( wxT(""), fc ); + wxVERIFY_FILECONFIG( "", fc ); - fc.Write(wxT("/Bar/Baz"), wxT("baz")); - wxVERIFY_FILECONFIG( wxT("[Bar]\nBaz=baz\n"), fc ); + fc.Write("/Bar/Baz", "baz"); + wxVERIFY_FILECONFIG( "[Bar]\nBaz=baz\n", fc ); - fc.Write(wxT("/Foo"), wxT("foo")); - wxVERIFY_FILECONFIG( wxT("Foo=foo\n[Bar]\nBaz=baz\n"), fc ); + fc.Write("/Foo", "foo"); + wxVERIFY_FILECONFIG( "Foo=foo\n[Bar]\nBaz=baz\n", fc ); } namespace @@ -97,11 +97,11 @@ namespace void CheckGroupEntries(const wxFileConfig& fc, - const wxChar *path, + const char *path, size_t nEntries, ...) { - wxConfigPathChanger change(&fc, wxString(path) + wxT("/")); + wxConfigPathChanger change(&fc, wxString(path) + "/"); CHECK( fc.GetNumberOfEntries() == nEntries ); @@ -114,7 +114,7 @@ CheckGroupEntries(const wxFileConfig& fc, cont; cont = fc.GetNextEntry(name, cookie), nEntries-- ) { - CHECK( name == va_arg(ap, wxChar *) ); + CHECK( name == va_arg(ap, char *) ); } CHECK( nEntries == 0 ); @@ -124,11 +124,11 @@ CheckGroupEntries(const wxFileConfig& fc, void CheckGroupSubgroups(const wxFileConfig& fc, - const wxChar *path, + const char *path, size_t nGroups, ...) { - wxConfigPathChanger change(&fc, wxString(path) + wxT("/")); + wxConfigPathChanger change(&fc, wxString(path) + "/"); CHECK( fc.GetNumberOfGroups() == nGroups ); @@ -141,7 +141,7 @@ CheckGroupSubgroups(const wxFileConfig& fc, cont; cont = fc.GetNextGroup(name, cookie), nGroups-- ) { - CHECK( name == va_arg(ap, wxChar *) ); + CHECK( name == va_arg(ap, char *) ); } CHECK( nGroups == 0 ); @@ -156,11 +156,11 @@ TEST_CASE("wxFileConfig::GetEntries", "[fileconfig][config]") wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CheckGroupEntries(fc, wxT(""), 0); - CheckGroupEntries(fc, wxT("/root"), 1, wxT("entry")); - CheckGroupEntries(fc, wxT("/root/group1"), 0); - CheckGroupEntries(fc, wxT("/root/group1/subgroup"), - 2, wxT("subentry"), wxT("subentry2")); + CheckGroupEntries(fc, "", 0); + CheckGroupEntries(fc, "/root", 1, "entry"); + CheckGroupEntries(fc, "/root/group1", 0); + CheckGroupEntries(fc, "/root/group1/subgroup", + 2, "subentry", "subentry2"); } TEST_CASE("wxFileConfig::GetGroups", "[fileconfig][config]") @@ -168,10 +168,10 @@ TEST_CASE("wxFileConfig::GetGroups", "[fileconfig][config]") wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CheckGroupSubgroups(fc, wxT(""), 1, wxT("root")); - CheckGroupSubgroups(fc, wxT("/root"), 2, wxT("group1"), wxT("group2")); - CheckGroupSubgroups(fc, wxT("/root/group1"), 1, wxT("subgroup")); - CheckGroupSubgroups(fc, wxT("/root/group2"), 0); + CheckGroupSubgroups(fc, "", 1, "root"); + CheckGroupSubgroups(fc, "/root", 2, "group1", "group2"); + CheckGroupSubgroups(fc, "/root/group1", 1, "subgroup"); + CheckGroupSubgroups(fc, "/root/group2", 0); } TEST_CASE("wxFileConfig::HasEntry", "[fileconfig][config]") @@ -179,15 +179,15 @@ TEST_CASE("wxFileConfig::HasEntry", "[fileconfig][config]") wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CHECK( !fc.HasEntry(wxT("root")) ); - CHECK( fc.HasEntry(wxT("root/entry")) ); - CHECK( fc.HasEntry(wxT("/root/entry")) ); - CHECK( fc.HasEntry(wxT("root/group1/subgroup/subentry")) ); - CHECK( !fc.HasEntry(wxT("")) ); - CHECK( !fc.HasEntry(wxT("root/group1")) ); - CHECK( !fc.HasEntry(wxT("subgroup/subentry")) ); - CHECK( !fc.HasEntry(wxT("/root/no_such_group/entry")) ); - CHECK( !fc.HasGroup(wxT("/root/no_such_group")) ); + CHECK( !fc.HasEntry("root") ); + CHECK( fc.HasEntry("root/entry") ); + CHECK( fc.HasEntry("/root/entry") ); + CHECK( fc.HasEntry("root/group1/subgroup/subentry") ); + CHECK( !fc.HasEntry("") ); + CHECK( !fc.HasEntry("root/group1") ); + CHECK( !fc.HasEntry("subgroup/subentry") ); + CHECK( !fc.HasEntry("/root/no_such_group/entry") ); + CHECK( !fc.HasGroup("/root/no_such_group") ); } TEST_CASE("wxFileConfig::HasGroup", "[fileconfig][config]") @@ -195,15 +195,15 @@ TEST_CASE("wxFileConfig::HasGroup", "[fileconfig][config]") wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CHECK( fc.HasGroup(wxT("root")) ); - CHECK( fc.HasGroup(wxT("root/group1")) ); - CHECK( fc.HasGroup(wxT("root/group1/subgroup")) ); - CHECK( fc.HasGroup(wxT("root/group2")) ); - CHECK( !fc.HasGroup(wxT("")) ); - CHECK( !fc.HasGroup(wxT("root/group")) ); - CHECK( !fc.HasGroup(wxT("root//subgroup")) ); - CHECK( !fc.HasGroup(wxT("foot/subgroup")) ); - CHECK( !fc.HasGroup(wxT("foot")) ); + CHECK( fc.HasGroup("root") ); + CHECK( fc.HasGroup("root/group1") ); + CHECK( fc.HasGroup("root/group1/subgroup") ); + CHECK( fc.HasGroup("root/group2") ); + CHECK( !fc.HasGroup("") ); + CHECK( !fc.HasGroup("root/group") ); + CHECK( !fc.HasGroup("root//subgroup") ); + CHECK( !fc.HasGroup("foot/subgroup") ); + CHECK( !fc.HasGroup("foot") ); } TEST_CASE("wxFileConfig::Binary", "[fileconfig][config]") @@ -242,24 +242,24 @@ TEST_CASE("wxFileConfig::DeleteEntry", "[fileconfig][config]") wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CHECK( !fc.DeleteEntry(wxT("foo")) ); + CHECK( !fc.DeleteEntry("foo") ); - CHECK( fc.DeleteEntry(wxT("root/group1/subgroup/subentry")) ); - wxVERIFY_FILECONFIG( wxT("[root]\n") - wxT("entry=value\n") - wxT("[root/group1]\n") - wxT("[root/group1/subgroup]\n") - wxT("subentry2=subvalue2\n") - wxT("[root/group2]\n"), + CHECK( fc.DeleteEntry("root/group1/subgroup/subentry") ); + wxVERIFY_FILECONFIG( "[root]\n" + "entry=value\n" + "[root/group1]\n" + "[root/group1/subgroup]\n" + "subentry2=subvalue2\n" + "[root/group2]\n", fc ); // group should be deleted now as well as it became empty - wxConfigPathChanger change(&fc, wxT("root/group1/subgroup/subentry2")); - CHECK( fc.DeleteEntry(wxT("subentry2")) ); - wxVERIFY_FILECONFIG( wxT("[root]\n") - wxT("entry=value\n") - wxT("[root/group1]\n") - wxT("[root/group2]\n"), + wxConfigPathChanger change(&fc, "root/group1/subgroup/subentry2"); + CHECK( fc.DeleteEntry("subentry2") ); + wxVERIFY_FILECONFIG( "[root]\n" + "entry=value\n" + "[root/group1]\n" + "[root/group2]\n", fc ); } @@ -327,21 +327,21 @@ TEST_CASE("wxFileConfig::DeleteGroup", "[fileconfig][config]") wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CHECK( !fc.DeleteGroup(wxT("foo")) ); + CHECK( !fc.DeleteGroup("foo") ); - CHECK( fc.DeleteGroup(wxT("root/group1")) ); - wxVERIFY_FILECONFIG( wxT("[root]\n") - wxT("entry=value\n") - wxT("[root/group2]\n"), + CHECK( fc.DeleteGroup("root/group1") ); + wxVERIFY_FILECONFIG( "[root]\n" + "entry=value\n" + "[root/group2]\n", fc ); // notice trailing slash: it should be ignored - CHECK( fc.DeleteGroup(wxT("root/group2/")) ); - wxVERIFY_FILECONFIG( wxT("[root]\n") - wxT("entry=value\n"), + CHECK( fc.DeleteGroup("root/group2/") ); + wxVERIFY_FILECONFIG( "[root]\n" + "entry=value\n", fc ); - CHECK( fc.DeleteGroup(wxT("root")) ); + CHECK( fc.DeleteGroup("root") ); CHECK( Dump(fc).empty() ); } @@ -359,29 +359,29 @@ TEST_CASE("wxFileConfig::RenameEntry", "[fileconfig][config]") wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - fc.SetPath(wxT("root")); - CHECK( fc.RenameEntry(wxT("entry"), wxT("newname")) ); - wxVERIFY_FILECONFIG( wxT("[root]\n") - wxT("newname=value\n") - wxT("[root/group1]\n") - wxT("[root/group1/subgroup]\n") - wxT("subentry=subvalue\n") - wxT("subentry2=subvalue2\n") - wxT("[root/group2]\n"), + fc.SetPath("root"); + CHECK( fc.RenameEntry("entry", "newname") ); + wxVERIFY_FILECONFIG( "[root]\n" + "newname=value\n" + "[root/group1]\n" + "[root/group1/subgroup]\n" + "subentry=subvalue\n" + "subentry2=subvalue2\n" + "[root/group2]\n", fc ); - fc.SetPath(wxT("group1/subgroup")); - CHECK( !fc.RenameEntry(wxT("entry"), wxT("newname")) ); - CHECK( !fc.RenameEntry(wxT("subentry"), wxT("subentry2")) ); + fc.SetPath("group1/subgroup"); + CHECK( !fc.RenameEntry("entry", "newname") ); + CHECK( !fc.RenameEntry("subentry", "subentry2") ); - CHECK( fc.RenameEntry(wxT("subentry"), wxT("subentry1")) ); - wxVERIFY_FILECONFIG( wxT("[root]\n") - wxT("newname=value\n") - wxT("[root/group1]\n") - wxT("[root/group1/subgroup]\n") - wxT("subentry2=subvalue2\n") - wxT("subentry1=subvalue\n") - wxT("[root/group2]\n"), + CHECK( fc.RenameEntry("subentry", "subentry1") ); + wxVERIFY_FILECONFIG( "[root]\n" + "newname=value\n" + "[root/group1]\n" + "[root/group1/subgroup]\n" + "subentry2=subvalue2\n" + "subentry1=subvalue\n" + "[root/group2]\n", fc ); } @@ -390,118 +390,118 @@ TEST_CASE("wxFileConfig::RenameGroup", "[fileconfig][config]") wxStringInputStream sis(testconfig); wxFileConfig fc(sis); - CHECK( fc.RenameGroup(wxT("root"), wxT("foot")) ); - wxVERIFY_FILECONFIG( wxT("[foot]\n") - wxT("entry=value\n") - wxT("[foot/group1]\n") - wxT("[foot/group1/subgroup]\n") - wxT("subentry=subvalue\n") - wxT("subentry2=subvalue2\n") - wxT("[foot/group2]\n"), + CHECK( fc.RenameGroup("root", "foot") ); + wxVERIFY_FILECONFIG( "[foot]\n" + "entry=value\n" + "[foot/group1]\n" + "[foot/group1/subgroup]\n" + "subentry=subvalue\n" + "subentry2=subvalue2\n" + "[foot/group2]\n", fc ); // renaming a path doesn't work, it must be the immediate group - CHECK( !fc.RenameGroup(wxT("foot/group1"), wxT("group2")) ); + CHECK( !fc.RenameGroup("foot/group1", "group2") ); - fc.SetPath(wxT("foot")); + fc.SetPath("foot"); // renaming to a name of existing group doesn't work - CHECK( !fc.RenameGroup(wxT("group1"), wxT("group2")) ); + CHECK( !fc.RenameGroup("group1", "group2") ); // try exchanging the groups names and then restore them back - CHECK( fc.RenameGroup(wxT("group1"), wxT("groupTmp")) ); - wxVERIFY_FILECONFIG( wxT("[foot]\n") - wxT("entry=value\n") - wxT("[foot/groupTmp]\n") - wxT("[foot/groupTmp/subgroup]\n") - wxT("subentry=subvalue\n") - wxT("subentry2=subvalue2\n") - wxT("[foot/group2]\n"), + CHECK( fc.RenameGroup("group1", "groupTmp") ); + wxVERIFY_FILECONFIG( "[foot]\n" + "entry=value\n" + "[foot/groupTmp]\n" + "[foot/groupTmp/subgroup]\n" + "subentry=subvalue\n" + "subentry2=subvalue2\n" + "[foot/group2]\n", fc ); - CHECK( fc.RenameGroup(wxT("group2"), wxT("group1")) ); - wxVERIFY_FILECONFIG( wxT("[foot]\n") - wxT("entry=value\n") - wxT("[foot/groupTmp]\n") - wxT("[foot/groupTmp/subgroup]\n") - wxT("subentry=subvalue\n") - wxT("subentry2=subvalue2\n") - wxT("[foot/group1]\n"), + CHECK( fc.RenameGroup("group2", "group1") ); + wxVERIFY_FILECONFIG( "[foot]\n" + "entry=value\n" + "[foot/groupTmp]\n" + "[foot/groupTmp/subgroup]\n" + "subentry=subvalue\n" + "subentry2=subvalue2\n" + "[foot/group1]\n", fc ); - CHECK( fc.RenameGroup(wxT("groupTmp"), wxT("group2")) ); - wxVERIFY_FILECONFIG( wxT("[foot]\n") - wxT("entry=value\n") - wxT("[foot/group2]\n") - wxT("[foot/group2/subgroup]\n") - wxT("subentry=subvalue\n") - wxT("subentry2=subvalue2\n") - wxT("[foot/group1]\n"), + CHECK( fc.RenameGroup("groupTmp", "group2") ); + wxVERIFY_FILECONFIG( "[foot]\n" + "entry=value\n" + "[foot/group2]\n" + "[foot/group2/subgroup]\n" + "subentry=subvalue\n" + "subentry2=subvalue2\n" + "[foot/group1]\n", fc ); - CHECK( fc.RenameGroup(wxT("group1"), wxT("groupTmp")) ); - wxVERIFY_FILECONFIG( wxT("[foot]\n") - wxT("entry=value\n") - wxT("[foot/group2]\n") - wxT("[foot/group2/subgroup]\n") - wxT("subentry=subvalue\n") - wxT("subentry2=subvalue2\n") - wxT("[foot/groupTmp]\n"), + CHECK( fc.RenameGroup("group1", "groupTmp") ); + wxVERIFY_FILECONFIG( "[foot]\n" + "entry=value\n" + "[foot/group2]\n" + "[foot/group2/subgroup]\n" + "subentry=subvalue\n" + "subentry2=subvalue2\n" + "[foot/groupTmp]\n", fc ); - CHECK( fc.RenameGroup(wxT("group2"), wxT("group1")) ); - wxVERIFY_FILECONFIG( wxT("[foot]\n") - wxT("entry=value\n") - wxT("[foot/group1]\n") - wxT("[foot/group1/subgroup]\n") - wxT("subentry=subvalue\n") - wxT("subentry2=subvalue2\n") - wxT("[foot/groupTmp]\n"), + CHECK( fc.RenameGroup("group2", "group1") ); + wxVERIFY_FILECONFIG( "[foot]\n" + "entry=value\n" + "[foot/group1]\n" + "[foot/group1/subgroup]\n" + "subentry=subvalue\n" + "subentry2=subvalue2\n" + "[foot/groupTmp]\n", fc ); - CHECK( fc.RenameGroup(wxT("groupTmp"), wxT("group2")) ); - wxVERIFY_FILECONFIG( wxT("[foot]\n") - wxT("entry=value\n") - wxT("[foot/group1]\n") - wxT("[foot/group1/subgroup]\n") - wxT("subentry=subvalue\n") - wxT("subentry2=subvalue2\n") - wxT("[foot/group2]\n"), + CHECK( fc.RenameGroup("groupTmp", "group2") ); + wxVERIFY_FILECONFIG( "[foot]\n" + "entry=value\n" + "[foot/group1]\n" + "[foot/group1/subgroup]\n" + "subentry=subvalue\n" + "subentry2=subvalue2\n" + "[foot/group2]\n", fc ); } TEST_CASE("wxFileConfig::CreateSubgroupAndEntries", "[fileconfig][config]") { wxFileConfig fc; - fc.Write(wxT("sub/sub_first"), wxT("sub_one")); - fc.Write(wxT("first"), wxT("one")); + fc.Write("sub/sub_first", "sub_one"); + fc.Write("first", "one"); - wxVERIFY_FILECONFIG( wxT("first=one\n") - wxT("[sub]\n") - wxT("sub_first=sub_one\n"), + wxVERIFY_FILECONFIG( "first=one\n" + "[sub]\n" + "sub_first=sub_one\n", fc ); } TEST_CASE("wxFileConfig::CreateEntriesAndSubgroup", "[fileconfig][config]") { wxFileConfig fc; - fc.Write(wxT("first"), wxT("one")); - fc.Write(wxT("second"), wxT("two")); - fc.Write(wxT("sub/sub_first"), wxT("sub_one")); + fc.Write("first", "one"); + fc.Write("second", "two"); + fc.Write("sub/sub_first", "sub_one"); - wxVERIFY_FILECONFIG( wxT("first=one\n") - wxT("second=two\n") - wxT("[sub]\n") - wxT("sub_first=sub_one\n"), + wxVERIFY_FILECONFIG( "first=one\n" + "second=two\n" + "[sub]\n" + "sub_first=sub_one\n", fc ); } static void EmptyConfigAndWriteKey() { - wxFileConfig fc(wxT("deleteconftest")); + wxFileConfig fc("deleteconftest"); - const wxString groupPath = wxT("/root"); + const wxString groupPath = "/root"; if ( fc.Exists(groupPath) ) { @@ -515,7 +515,7 @@ static void EmptyConfigAndWriteKey() // this crashes on second call of this function - CHECK( fc.Write(groupPath + wxT("/entry"), wxT("value")) ); + CHECK( fc.Write(groupPath + "/entry", "value") ); } TEST_CASE("wxFileConfig::DeleteLastGroup", "[fileconfig][config]") @@ -535,47 +535,47 @@ TEST_CASE("wxFileConfig::DeleteLastGroup", "[fileconfig][config]") // clean up wxLogNull noLogging; - (void) ::wxRemoveFile(wxFileConfig::GetLocalFileName(wxT("deleteconftest"))); + (void) ::wxRemoveFile(wxFileConfig::GetLocalFileName("deleteconftest")); } TEST_CASE("wxFileConfig::DeleteAndRecreateGroup", "[fileconfig][config]") { - static const wxChar *confInitial = - wxT("[First]\n") - wxT("Value1=Foo\n") - wxT("[Second]\n") - wxT("Value2=Bar\n"); + static const char *confInitial = + "[First]\n" + "Value1=Foo\n" + "[Second]\n" + "Value2=Bar\n"; wxStringInputStream sis(confInitial); wxFileConfig fc(sis); - fc.DeleteGroup(wxT("Second")); - wxVERIFY_FILECONFIG( wxT("[First]\n") - wxT("Value1=Foo\n"), + fc.DeleteGroup("Second"); + wxVERIFY_FILECONFIG( "[First]\n" + "Value1=Foo\n", fc ); - fc.Write(wxT("Second/Value2"), wxT("New")); - wxVERIFY_FILECONFIG( wxT("[First]\n") - wxT("Value1=Foo\n") - wxT("[Second]\n") - wxT("Value2=New\n"), + fc.Write("Second/Value2", "New"); + wxVERIFY_FILECONFIG( "[First]\n" + "Value1=Foo\n" + "[Second]\n" + "Value2=New\n", fc ); } TEST_CASE("wxFileConfig::AddToExistingRoot", "[fileconfig][config]") { - static const wxChar *confInitial = - wxT("[Group]\n") - wxT("value1=foo\n"); + static const char *confInitial = + "[Group]\n" + "value1=foo\n"; wxStringInputStream sis(confInitial); wxFileConfig fc(sis); - fc.Write(wxT("/value1"), wxT("bar")); + fc.Write("/value1", "bar"); wxVERIFY_FILECONFIG( - wxT("value1=bar\n") - wxT("[Group]\n") - wxT("value1=foo\n"), + "value1=bar\n" + "[Group]\n" + "value1=foo\n", fc ); } diff --git a/tests/config/regconf.cpp b/tests/config/regconf.cpp index 052a58444a..623f503918 100644 --- a/tests/config/regconf.cpp +++ b/tests/config/regconf.cpp @@ -28,31 +28,31 @@ TEST_CASE("wxRegConfig::ReadWrite", "[regconfig][config][registry]") { - wxString app = wxT("wxRegConfigTestCase"); - wxString vendor = wxT("wxWidgets"); + wxString app = "wxRegConfigTestCase"; + wxString vendor = "wxWidgets"; // NOTE: we use wxCONFIG_USE_LOCAL_FILE explicitly to test wxRegConfig // with something different from the default value wxCONFIG_USE_GLOBAL_FILE - wxScopedPtr config(new wxRegConfig(app, vendor, wxT(""), wxT(""), + wxScopedPtr config(new wxRegConfig(app, vendor, "", "", wxCONFIG_USE_LOCAL_FILE)); // test writing - config->SetPath(wxT("/group1")); - CHECK( config->Write(wxT("entry1"), wxT("foo")) ); - config->SetPath(wxT("/group2")); - CHECK( config->Write(wxT("entry1"), wxT("bar")) ); + config->SetPath("/group1"); + CHECK( config->Write("entry1", "foo") ); + config->SetPath("/group2"); + CHECK( config->Write("entry1", "bar") ); // test reading wxString str; long dummy; - config->SetPath(wxT("/")); + config->SetPath("/"); CHECK( config->GetFirstGroup(str, dummy) ); CHECK( str == "group1" ); - CHECK( config->Read(wxT("group1/entry1"), wxT("INVALID DEFAULT")) == "foo" ); + CHECK( config->Read("group1/entry1", "INVALID DEFAULT") == "foo" ); CHECK( config->GetNextGroup(str, dummy) ); CHECK( str == "group2" ); - CHECK( config->Read(wxT("group2/entry1"), wxT("INVALID DEFAULT")) == "bar" ); + CHECK( config->Read("group2/entry1", "INVALID DEFAULT") == "bar" ); config->DeleteAll(); } From eb33447c3986417690acbc5733efeeebf67244d3 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Mar 2021 18:53:46 +0100 Subject: [PATCH 4/8] Use template function to avoid code duplication in wxRegConfig Don't repeat exactly the same code for 3 different types, just use a template function instead. Change the existing TryGetValue() helpers to take all output parameters consistently by pointer, rather than taking only long by pointer and the other by reference. This allows to isolate the inconsistency of the type of wxRegKey::QueryValue() parameter in a single place here, hiding it from the rest of wxRegConfig code. Add an extra unit test for writing/reading longs to/from wxRegConfig. --- include/wx/msw/regconf.h | 6 ++ src/msw/regconf.cpp | 115 +++++++++------------------------------ tests/config/regconf.cpp | 4 ++ 3 files changed, 36 insertions(+), 89 deletions(-) diff --git a/include/wx/msw/regconf.h b/include/wx/msw/regconf.h index 0082c139a6..705dafdfa7 100644 --- a/include/wx/msw/regconf.h +++ b/include/wx/msw/regconf.h @@ -88,6 +88,12 @@ protected: return self->m_keyLocal; } + // Type-independent implementation of Do{Read,Write}Foo(). + template + bool DoReadValue(const wxString& key, T* pValue) const; + template + bool DoWriteValue(const wxString& key, const T& value); + // implement read/write methods virtual bool DoReadString(const wxString& key, wxString *pStr) const wxOVERRIDE; virtual bool DoReadLong(const wxString& key, long *plResult) const wxOVERRIDE; diff --git a/src/msw/regconf.cpp b/src/msw/regconf.cpp index eeb3c90639..5ea2409164 100644 --- a/src/msw/regconf.cpp +++ b/src/msw/regconf.cpp @@ -39,9 +39,9 @@ // ---------------------------------------------------------------------------- // get the value if the key is opened and it exists -bool TryGetValue(const wxRegKey& key, const wxString& str, wxString& strVal) +bool TryGetValue(const wxRegKey& key, const wxString& str, wxString* strVal) { - return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, strVal); + return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, *strVal); } bool TryGetValue(const wxRegKey& key, const wxString& str, long *plVal) @@ -49,9 +49,9 @@ bool TryGetValue(const wxRegKey& key, const wxString& str, long *plVal) return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, plVal); } -bool TryGetValue(const wxRegKey& key, const wxString& str, wxMemoryBuffer &plVal) +bool TryGetValue(const wxRegKey& key, const wxString& str, wxMemoryBuffer* pBuf) { - return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, plVal); + return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, *pBuf); } // ============================================================================ @@ -550,9 +550,10 @@ wxConfigBase::EntryType wxRegConfig::GetEntryType(const wxString& key) const // reading/writing // ---------------------------------------------------------------------------- -bool wxRegConfig::DoReadString(const wxString& key, wxString *pStr) const +template +bool wxRegConfig::DoReadValue(const wxString& key, T* pValue) const { - wxCHECK_MSG( pStr, false, wxT("wxRegConfig::Read(): NULL param") ); + wxCHECK_MSG( pValue, false, wxT("wxRegConfig::Read(): NULL param") ); wxConfigPathChanger path(this, key); @@ -561,7 +562,7 @@ bool wxRegConfig::DoReadString(const wxString& key, wxString *pStr) const // if immutable key exists in global key we must check that it's not // overridden by the local key with the same name if ( IsImmutable(path.Name()) ) { - if ( TryGetValue(m_keyGlobal, path.Name(), *pStr) ) { + if ( TryGetValue(m_keyGlobal, path.Name(), pValue) ) { if ( m_keyLocal.Exists() && LocalKey().HasValue(path.Name()) ) { wxLogWarning(wxT("User value for immutable key '%s' ignored."), path.Name().c_str()); @@ -576,88 +577,33 @@ bool wxRegConfig::DoReadString(const wxString& key, wxString *pStr) const } // first try local key - if ( (m_keyLocal.Exists() && TryGetValue(LocalKey(), path.Name(), *pStr)) || - (bQueryGlobal && TryGetValue(m_keyGlobal, path.Name(), *pStr)) ) { + if ( (m_keyLocal.Exists() && TryGetValue(LocalKey(), path.Name(), pValue)) || + (bQueryGlobal && TryGetValue(m_keyGlobal, path.Name(), pValue)) ) { return true; } return false; } -// this exactly reproduces the string version above except for ExpandEnvVars(), -// we really should avoid this code duplication somehow... +bool wxRegConfig::DoReadString(const wxString& key, wxString *pStr) const +{ + return DoReadValue(key, pStr); +} bool wxRegConfig::DoReadLong(const wxString& key, long *plResult) const { - wxCHECK_MSG( plResult, false, wxT("wxRegConfig::Read(): NULL param") ); - - wxConfigPathChanger path(this, key); - - bool bQueryGlobal = true; - - // if immutable key exists in global key we must check that it's not - // overridden by the local key with the same name - if ( IsImmutable(path.Name()) ) { - if ( TryGetValue(m_keyGlobal, path.Name(), plResult) ) { - if ( m_keyLocal.Exists() && LocalKey().HasValue(path.Name()) ) { - wxLogWarning(wxT("User value for immutable key '%s' ignored."), - path.Name().c_str()); - } - - return true; - } - else { - // don't waste time - it's not there anyhow - bQueryGlobal = false; - } - } - - // first try local key - if ( (m_keyLocal.Exists() && TryGetValue(LocalKey(), path.Name(), plResult)) || - (bQueryGlobal && TryGetValue(m_keyGlobal, path.Name(), plResult)) ) { - return true; - } - - return false; + return DoReadValue(key, plResult); } #if wxUSE_BASE64 bool wxRegConfig::DoReadBinary(const wxString& key, wxMemoryBuffer *buf) const { - wxCHECK_MSG( buf, false, wxT("wxRegConfig::Read(): NULL param") ); - - wxConfigPathChanger path(this, key); - - bool bQueryGlobal = true; - - // if immutable key exists in global key we must check that it's not - // overridden by the local key with the same name - if ( IsImmutable(path.Name()) ) { - if ( TryGetValue(m_keyGlobal, path.Name(), *buf) ) { - if ( m_keyLocal.Exists() && LocalKey().HasValue(path.Name()) ) { - wxLogWarning(wxT("User value for immutable key '%s' ignored."), - path.Name().c_str()); - } - - return true; - } - else { - // don't waste time - it's not there anyhow - bQueryGlobal = false; - } - } - - // first try local key - if ( (m_keyLocal.Exists() && TryGetValue(LocalKey(), path.Name(), *buf)) || - (bQueryGlobal && TryGetValue(m_keyGlobal, path.Name(), *buf)) ) { - return true; - } - - return false; + return DoReadValue(key, buf); } #endif // wxUSE_BASE64 -bool wxRegConfig::DoWriteString(const wxString& key, const wxString& szValue) +template +bool wxRegConfig::DoWriteValue(const wxString& key, const T& value) { wxConfigPathChanger path(this, key); @@ -666,32 +612,23 @@ bool wxRegConfig::DoWriteString(const wxString& key, const wxString& szValue) return false; } - return LocalKey().SetValue(path.Name(), szValue); + return LocalKey().SetValue(path.Name(), value); +} + +bool wxRegConfig::DoWriteString(const wxString& key, const wxString& szValue) +{ + return DoWriteValue(key, szValue); } bool wxRegConfig::DoWriteLong(const wxString& key, long lValue) { - wxConfigPathChanger path(this, key); - - if ( IsImmutable(path.Name()) ) { - wxLogError(wxT("Can't change immutable entry '%s'."), path.Name().c_str()); - return false; - } - - return LocalKey().SetValue(path.Name(), lValue); + return DoWriteValue(key, lValue); } #if wxUSE_BASE64 bool wxRegConfig::DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf) { - wxConfigPathChanger path(this, key); - - if ( IsImmutable(path.Name()) ) { - wxLogError(wxT("Can't change immutable entry '%s'."), path.Name().c_str()); - return false; - } - - return LocalKey().SetValue(path.Name(), buf); + return DoWriteValue(key, buf); } #endif // wxUSE_BASE64 diff --git a/tests/config/regconf.cpp b/tests/config/regconf.cpp index 623f503918..ab012cb544 100644 --- a/tests/config/regconf.cpp +++ b/tests/config/regconf.cpp @@ -42,6 +42,8 @@ TEST_CASE("wxRegConfig::ReadWrite", "[regconfig][config][registry]") config->SetPath("/group2"); CHECK( config->Write("entry1", "bar") ); + CHECK( config->Write("int32", 1234567) ); + // test reading wxString str; long dummy; @@ -54,6 +56,8 @@ TEST_CASE("wxRegConfig::ReadWrite", "[regconfig][config][registry]") CHECK( str == "group2" ); CHECK( config->Read("group2/entry1", "INVALID DEFAULT") == "bar" ); + CHECK( config->ReadLong("group2/int32", 0) == 1234567 ); + config->DeleteAll(); } From 3f2c84d4a92de1e9c177d1ffe9ba2618956be7ec Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Mar 2021 21:09:42 +0100 Subject: [PATCH 5/8] Add 64-bit numbers support to wxRegKey This uses the native registry support for 64-bit values available since Windows XP. Note that SetValue64() can't be just called SetValue() as this would introduce ambiguities when writing an int or an enum to the registry. This could be avoided by providing overloads for all the arithmetic types, but it's arguably better to be more clear about what exactly is being written to the registry in this low-level class and using a different name is definitely simpler. --- include/wx/msw/registry.h | 11 ++++++--- interface/wx/msw/registry.h | 19 ++++++++++++++ src/msw/registry.cpp | 49 +++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/include/wx/msw/registry.h b/include/wx/msw/registry.h index ae43a075ba..482f49f05c 100644 --- a/include/wx/msw/registry.h +++ b/include/wx/msw/registry.h @@ -42,7 +42,8 @@ public: Type_Multi_String, // Multiple Unicode strings Type_Resource_list, // Resource list in the resource map Type_Full_resource_descriptor, // Resource list in the hardware description - Type_Resource_requirements_list // ??? + Type_Resource_requirements_list, // ??? + Type_Qword // 64-bit number }; // predefined registry keys @@ -197,10 +198,14 @@ public: // retrieve either raw or expanded string value bool QueryValue(const wxString& szValue, wxString& strValue, bool raw) const; - // set the numeric value + // set the 32-bit numeric value bool SetValue(const wxString& szValue, long lValue); - // return the numeric value + // return the 32-bit numeric value bool QueryValue(const wxString& szValue, long *plValue) const; + // set the 64-bit numeric value + bool SetValue64(const wxString& szValue, wxLongLong_t llValue); + // return the 64-bit numeric value + bool QueryValue64(const wxString& szValue, wxLongLong_t *pllValue) const; // set the binary value bool SetValue(const wxString& szValue, const wxMemoryBuffer& buf); // return the binary value diff --git a/interface/wx/msw/registry.h b/interface/wx/msw/registry.h index 3bacdcded0..2d887d0b8a 100644 --- a/interface/wx/msw/registry.h +++ b/interface/wx/msw/registry.h @@ -350,6 +350,14 @@ public: */ bool QueryValue(const wxString& szValue, long* plValue) const; + /** + Retrieves the 64-bit value. Returns @true if successful. + An empty @a szValue queries the default/unnamed key value. + + @since 3.1.5 + */ + bool QueryValue64(const wxString& szValue, wxLongLong_t* plValue) const; + /** Retrieves the binary structure. Returns @true if successful. An empty @a szValue queries the default/unnamed key value. @@ -397,6 +405,17 @@ public: An empty @a szValue sets the default/unnamed key value. */ bool SetValue(const wxString& szValue, long lValue); + + /** + Sets a 64-bit value. + + This function creates or modifies a field of @c QWORD type in the + registry. + + @since 3.1.5 + */ + bool SetValue64(const wxString& szValue, wxLongLong_t lValue); + /** Sets the given @a szValue which must be string. If the value doesn't exist, it is created. Returns @true if successful. diff --git a/src/msw/registry.cpp b/src/msw/registry.cpp index a4b14436e7..186e048660 100644 --- a/src/msw/registry.cpp +++ b/src/msw/registry.cpp @@ -913,6 +913,54 @@ bool wxRegKey::QueryValue(const wxString& szValue, long *plValue) const return false; } +bool wxRegKey::SetValue64(const wxString& szValue, wxLongLong_t llValue) +{ + if ( CONST_CAST Open() ) { + m_dwLastError = RegSetValueEx((HKEY) m_hKey, RegValueStr(szValue), + wxRESERVED_PARAM, REG_QWORD, + (RegString)&llValue, sizeof(llValue)); + if ( m_dwLastError == ERROR_SUCCESS ) + return true; + } + + wxLogSysError(m_dwLastError, _("Can't set value of '%s'"), + GetFullName(this, szValue)); + return false; +} + +bool wxRegKey::QueryValue64(const wxString& szValue, wxLongLong_t *pllValue) const +{ + if ( CONST_CAST Open(Read) ) { + DWORD dwType, dwSize = sizeof(wxLongLong_t); // QWORD doesn't exist. + RegString pBuf = (RegString)pllValue; + m_dwLastError = RegQueryValueEx((HKEY) m_hKey, RegValueStr(szValue), + wxRESERVED_PARAM, + &dwType, pBuf, &dwSize); + if ( m_dwLastError != ERROR_SUCCESS ) { + wxLogSysError(m_dwLastError, _("Can't read value of key '%s'"), + GetName().c_str()); + return false; + } + + // check that we read the value of right type + switch ( dwType ) + { + case REG_DWORD_LITTLE_ENDIAN: + case REG_DWORD_BIG_ENDIAN: + case REG_QWORD: + break; + + default: + wxLogError(_("Registry value \"%s\" is not numeric (but of type %s)"), + GetFullName(this, szValue), GetTypeString(dwType)); + return false; + } + + return true; + } + else + return false; +} bool wxRegKey::SetValue(const wxString& szValue, const wxMemoryBuffer& buffer) { if ( CONST_CAST Open() ) { @@ -1175,6 +1223,7 @@ bool wxRegKey::IsNumericValue(const wxString& szValue) const case Type_Dword: /* case Type_Dword_little_endian: == Type_Dword */ case Type_Dword_big_endian: + case Type_Qword: return true; default: From fce87802978a1029ac147bf22b16fe263d1b1345 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Mar 2021 21:17:26 +0100 Subject: [PATCH 6/8] Add 64-bit integers support to wxConfig Serialize them to strings in wxFileConfig, just as we always did for long, but use wxRegKey support for storing them directly to the registry in wxRegConfig. --- include/wx/confbase.h | 23 +++++++++++++++++++++++ include/wx/fileconf.h | 6 ++++++ include/wx/msw/regconf.h | 2 ++ interface/wx/config.h | 38 ++++++++++++++++++++++++++++++++++++++ src/common/config.cpp | 7 +++++-- src/common/fileconf.cpp | 24 ++++++++++++++++++++++++ src/msw/regconf.cpp | 30 +++++++++++++++++++++++++++++- tests/config/config.cpp | 17 +++++++++++++++++ tests/config/fileconf.cpp | 13 +++++++++++++ tests/config/regconf.cpp | 7 +++++++ 10 files changed, 164 insertions(+), 3 deletions(-) diff --git a/include/wx/confbase.h b/include/wx/confbase.h index 5f5d44e8ac..88e4c641ba 100644 --- a/include/wx/confbase.h +++ b/include/wx/confbase.h @@ -186,6 +186,12 @@ public: bool Read(const wxString& key, bool* val) const; bool Read(const wxString& key, bool* val, bool defVal) const; + // read a 64-bit number when long is 32 bits +#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + bool Read(const wxString& key, wxLongLong_t *pl) const; + bool Read(const wxString& key, wxLongLong_t *pl, wxLongLong_t defVal) const; +#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + #if wxUSE_BASE64 // read a binary data block bool Read(const wxString& key, wxMemoryBuffer* data) const @@ -235,6 +241,9 @@ public: long ReadLong(const wxString& key, long defVal) const { long l; (void)Read(key, &l, defVal); return l; } + wxLongLong_t ReadLongLong(const wxString& key, wxLongLong_t defVal) const + { wxLongLong_t ll; (void)Read(key, &ll, defVal); return ll; } + double ReadDouble(const wxString& key, double defVal) const { double d; (void)Read(key, &d, defVal); return d; } @@ -304,6 +313,14 @@ public: bool Write(const wxString& key, unsigned long value) { return DoWriteLong(key, value); } +#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + bool Write(const wxString& key, wxLongLong_t value) + { return DoWriteLongLong(key, value); } + + bool Write(const wxString& key, wxULongLong_t value) + { return DoWriteLongLong(key, value); } +#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + bool Write(const wxString& key, float value) { return DoWriteDouble(key, double(value)); } @@ -374,6 +391,9 @@ protected: // do read/write the values of different types virtual bool DoReadString(const wxString& key, wxString *pStr) const = 0; virtual bool DoReadLong(const wxString& key, long *pl) const = 0; +#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + virtual bool DoReadLongLong(const wxString& key, wxLongLong_t *pll) const = 0; +#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG virtual bool DoReadDouble(const wxString& key, double* val) const; virtual bool DoReadBool(const wxString& key, bool* val) const; #if wxUSE_BASE64 @@ -382,6 +402,9 @@ protected: virtual bool DoWriteString(const wxString& key, const wxString& value) = 0; virtual bool DoWriteLong(const wxString& key, long value) = 0; +#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + virtual bool DoWriteLongLong(const wxString& key, wxLongLong_t value) = 0; +#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG virtual bool DoWriteDouble(const wxString& key, double value); virtual bool DoWriteBool(const wxString& key, bool value); #if wxUSE_BASE64 diff --git a/include/wx/fileconf.h b/include/wx/fileconf.h index fd392da194..8286b060ac 100644 --- a/include/wx/fileconf.h +++ b/include/wx/fileconf.h @@ -196,12 +196,18 @@ public: protected: virtual bool DoReadString(const wxString& key, wxString *pStr) const wxOVERRIDE; virtual bool DoReadLong(const wxString& key, long *pl) const wxOVERRIDE; +#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + virtual bool DoReadLongLong(const wxString& key, wxLongLong_t *pll) const wxOVERRIDE; +#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG #if wxUSE_BASE64 virtual bool DoReadBinary(const wxString& key, wxMemoryBuffer* buf) const wxOVERRIDE; #endif // wxUSE_BASE64 virtual bool DoWriteString(const wxString& key, const wxString& szValue) wxOVERRIDE; virtual bool DoWriteLong(const wxString& key, long lValue) wxOVERRIDE; +#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + virtual bool DoWriteLongLong(const wxString& key, wxLongLong_t value) wxOVERRIDE; +#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG #if wxUSE_BASE64 virtual bool DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf) wxOVERRIDE; #endif // wxUSE_BASE64 diff --git a/include/wx/msw/regconf.h b/include/wx/msw/regconf.h index 705dafdfa7..6c7c0a98af 100644 --- a/include/wx/msw/regconf.h +++ b/include/wx/msw/regconf.h @@ -97,12 +97,14 @@ protected: // implement read/write methods virtual bool DoReadString(const wxString& key, wxString *pStr) const wxOVERRIDE; virtual bool DoReadLong(const wxString& key, long *plResult) const wxOVERRIDE; + virtual bool DoReadLongLong(const wxString& key, wxLongLong_t *pll) const wxOVERRIDE; #if wxUSE_BASE64 virtual bool DoReadBinary(const wxString& key, wxMemoryBuffer* buf) const wxOVERRIDE; #endif // wxUSE_BASE64 virtual bool DoWriteString(const wxString& key, const wxString& szValue) wxOVERRIDE; virtual bool DoWriteLong(const wxString& key, long lValue) wxOVERRIDE; + virtual bool DoWriteLongLong(const wxString& key, wxLongLong_t llValue) wxOVERRIDE; #if wxUSE_BASE64 virtual bool DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf) wxOVERRIDE; #endif // wxUSE_BASE64 diff --git a/interface/wx/config.h b/interface/wx/config.h index bff8d675eb..6d579480c0 100644 --- a/interface/wx/config.h +++ b/interface/wx/config.h @@ -549,6 +549,29 @@ public: */ bool Read(const wxString& key, long* l, long defaultVal) const; + /** + Reads a 64-bit long long value, returning @true if the value was found. + If the value was not found, @a ll is not changed. + + @since 3.1.5 + + @beginWxPerlOnly + Not supported by wxPerl. + @endWxPerlOnly + */ + bool Read(const wxString& key, wxLongLong_t* ll) const; + /** + Reads a 64-bit long long value, returning @true if the value was found. + If the value was not found, @a defaultVal is used instead. + + @since 3.1.5 + + @beginWxPerlOnly + Not supported by wxPerl. + @endWxPerlOnly + */ + bool Read(const wxString& key, wxLongLong_t* ll, + wxLongLong_t defaultVal) const; /** Reads a double value, returning @true if the value was found. If the value was not found, @a d is not changed. @@ -662,6 +685,14 @@ public: */ long ReadLong(const wxString& key, long defaultVal) const; + /** + Reads a 64-bit long long value from the key and returns it. @a + defaultVal is returned if the key is not found. + + @since 3.1.5 + */ + wxLongLong_t ReadLongLong(const wxString& key, wxLongLong_t defaultVal) const; + /** Reads a value of type T (for which the function wxFromString() must be defined) from the key and returns it. @a defaultVal is returned if the @@ -678,6 +709,13 @@ public: Writes the long value to the config file and returns @true on success. */ bool Write(const wxString& key, long value); + /** + Writes the 64-bit long long value to the config file and returns @true + on success. + + @since 3.1.5 + */ + bool Write(const wxString& key, wxLongLong_t value); /** Writes the double value to the config file and returns @true on success. diff --git a/src/common/config.cpp b/src/common/config.cpp index 6cbded738d..22ff3fa5d1 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -120,7 +120,7 @@ wxConfigBase *wxConfigBase::Create() if ( !DoRead##name(key, val) ) \ return false; \ \ - *val = extra(*val); \ + *val = (extra)(*val); \ \ return true; \ } \ @@ -142,7 +142,7 @@ wxConfigBase *wxConfigBase::Create() *val = defVal; \ } \ \ - *val = extra(*val); \ + *val = (extra)(*val); \ \ return read; \ } @@ -150,6 +150,9 @@ wxConfigBase *wxConfigBase::Create() IMPLEMENT_READ_FOR_TYPE(String, wxString, const wxString&, ExpandEnvVars) IMPLEMENT_READ_FOR_TYPE(Long, long, long, long) +#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG +IMPLEMENT_READ_FOR_TYPE(LongLong, wxLongLong_t, wxLongLong_t, wxLongLong_t) +#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG IMPLEMENT_READ_FOR_TYPE(Double, double, double, double) IMPLEMENT_READ_FOR_TYPE(Bool, bool, bool, bool) diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index c13327ae67..af5d02b0d3 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -881,6 +881,21 @@ bool wxFileConfig::DoReadLong(const wxString& key, long *pl) const return str.ToLong(pl); } +#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + +bool wxFileConfig::DoReadLongLong(const wxString& key, wxLongLong_t *pll) const +{ + wxString str; + if ( !Read(key, &str) ) + return false; + + str.Trim(); + + return str.ToLongLong(pll); +} + +#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + #if wxUSE_BASE64 bool wxFileConfig::DoReadBinary(const wxString& key, wxMemoryBuffer* buf) const @@ -962,6 +977,15 @@ bool wxFileConfig::DoWriteLong(const wxString& key, long lValue) return Write(key, wxString::Format(wxT("%ld"), lValue)); } +#ifdef wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + +bool wxFileConfig::DoWriteLongLong(const wxString& key, wxLongLong_t llValue) +{ + return Write(key, wxString::Format("%" wxLongLongFmtSpec "d", llValue)); +} + +#endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + #if wxUSE_BASE64 bool wxFileConfig::DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf) diff --git a/src/msw/regconf.cpp b/src/msw/regconf.cpp index 5ea2409164..872f693a2f 100644 --- a/src/msw/regconf.cpp +++ b/src/msw/regconf.cpp @@ -49,11 +49,29 @@ bool TryGetValue(const wxRegKey& key, const wxString& str, long *plVal) return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, plVal); } +bool TryGetValue(const wxRegKey& key, const wxString& str, wxLongLong_t *pll) +{ + return key.IsOpened() && key.HasValue(str) && key.QueryValue64(str, pll); +} + bool TryGetValue(const wxRegKey& key, const wxString& str, wxMemoryBuffer* pBuf) { return key.IsOpened() && key.HasValue(str) && key.QueryValue(str, *pBuf); } +// set value of the key in a homogeneous way to hide the differences between +// wxRegKey::SetValue() and SetValue64() +template +bool SetKeyValue(wxRegKey& key, const wxString& name, const T& value) +{ + return key.SetValue(name, value); +} + +bool SetKeyValue(wxRegKey& key, const wxString& name, wxLongLong_t value) +{ + return key.SetValue64(name, value); +} + // ============================================================================ // implementation // ============================================================================ @@ -595,6 +613,11 @@ bool wxRegConfig::DoReadLong(const wxString& key, long *plResult) const return DoReadValue(key, plResult); } +bool wxRegConfig::DoReadLongLong(const wxString& key, wxLongLong_t *pll) const +{ + return DoReadValue(key, pll); +} + #if wxUSE_BASE64 bool wxRegConfig::DoReadBinary(const wxString& key, wxMemoryBuffer *buf) const { @@ -612,7 +635,7 @@ bool wxRegConfig::DoWriteValue(const wxString& key, const T& value) return false; } - return LocalKey().SetValue(path.Name(), value); + return SetKeyValue(LocalKey(), path.Name(), value); } bool wxRegConfig::DoWriteString(const wxString& key, const wxString& szValue) @@ -625,6 +648,11 @@ bool wxRegConfig::DoWriteLong(const wxString& key, long lValue) return DoWriteValue(key, lValue); } +bool wxRegConfig::DoWriteLongLong(const wxString& key, wxLongLong_t llValue) +{ + return DoWriteValue(key, llValue); +} + #if wxUSE_BASE64 bool wxRegConfig::DoWriteBinary(const wxString& key, const wxMemoryBuffer& buf) { diff --git a/tests/config/config.cpp b/tests/config/config.cpp index c7f12ba2b0..1b60d1ccdd 100644 --- a/tests/config/config.cpp +++ b/tests/config/config.cpp @@ -45,6 +45,14 @@ TEST_CASE("wxConfig::ReadWriteLocal", "[config]") config->Write(wxString("long1"), 234L); config->Write("double1", 345.67); config->Write("bool1", true); + + // See comment in regconf.cpp. + const wxLongLong_t val64 = wxLL(0x8000000000000008); + config->Write("ll", val64); + + const wxULongLong_t uval64 = wxULL(0x9000000000000009); + config->Write("ull", uval64); + #ifdef wxHAS_CONFIG_TEMPLATE_RW config->Write("color1", wxColour(11,22,33,44)); #endif // wxHAS_CONFIG_TEMPLATE_RW @@ -93,6 +101,15 @@ TEST_CASE("wxConfig::ReadWriteLocal", "[config]") CHECK( config->ReadBool("bool1", false) == bool1 ); + wxLongLong_t ll; + CHECK( config->Read("ll", &ll) ); + CHECK( ll == val64 ); + CHECK( config->ReadLongLong("ll", 0) == val64 ); + + CHECK( config->Read("ull", &ll) ); + CHECK( ll == static_cast(uval64) ); + CHECK( config->ReadLongLong("ull", 0) == static_cast(uval64) ); + #ifdef wxHAS_CONFIG_TEMPLATE_RW wxColour color1; r = config->Read("color1", &color1); diff --git a/tests/config/fileconf.cpp b/tests/config/fileconf.cpp index 0d64f3a114..5b860a911d 100644 --- a/tests/config/fileconf.cpp +++ b/tests/config/fileconf.cpp @@ -626,5 +626,18 @@ TEST_CASE("wxFileConfig::ReadFloat", "[fileconfig][config]") CHECK( f == -9876.5432f ); } +TEST_CASE("wxFileConfig::LongLong", "[fileconfig][config][longlong]") +{ + wxFileConfig fc("", "", "", "", 0); // Don't use any files. + + // See comment near val64 definition in regconf.cpp. + const wxLongLong_t val = wxLL(0x8000000000000008); + REQUIRE( fc.Write("ll", val) ); + + wxLongLong_t ll; + REQUIRE( fc.Read("ll", &ll) ); + CHECK( ll == val ); +} + #endif // wxUSE_FILECONFIG diff --git a/tests/config/regconf.cpp b/tests/config/regconf.cpp index ab012cb544..0db7f4ebd7 100644 --- a/tests/config/regconf.cpp +++ b/tests/config/regconf.cpp @@ -44,6 +44,12 @@ TEST_CASE("wxRegConfig::ReadWrite", "[regconfig][config][registry]") CHECK( config->Write("int32", 1234567) ); + // Note that type of wxLL(0x8000000000000008) literal is somehow unsigned + // long long with MinGW, not sure if it's a bug or not, but work around it + // by specifying the type explicitly. + const wxLongLong_t val64 = wxLL(0x8000000000000008); + CHECK( config->Write("int64", val64) ); + // test reading wxString str; long dummy; @@ -57,6 +63,7 @@ TEST_CASE("wxRegConfig::ReadWrite", "[regconfig][config][registry]") CHECK( config->Read("group2/entry1", "INVALID DEFAULT") == "bar" ); CHECK( config->ReadLong("group2/int32", 0) == 1234567 ); + CHECK( config->ReadLongLong("group2/int64", 0) == val64 ); config->DeleteAll(); } From 0c837e5310998e4d57bc1f37cdfc170eb3dad49e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Mar 2021 21:33:30 +0100 Subject: [PATCH 7/8] Add support for size_t to wxConfig Allow writing and reading size_t values directly too, there were not previously accepted unlike all the other arithmetic types. Closes #19091. --- include/wx/confbase.h | 3 +++ interface/wx/config.h | 24 +++++++++++++++++++++++- src/common/config.cpp | 34 ++++++++++++++++++++++++++++++++++ tests/config/config.cpp | 5 +++++ 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/include/wx/confbase.h b/include/wx/confbase.h index 88e4c641ba..9073d602d5 100644 --- a/include/wx/confbase.h +++ b/include/wx/confbase.h @@ -192,6 +192,9 @@ public: bool Read(const wxString& key, wxLongLong_t *pl, wxLongLong_t defVal) const; #endif // wxHAS_LONG_LONG_T_DIFFERENT_FROM_LONG + bool Read(const wxString& key, size_t* val) const; + bool Read(const wxString& key, size_t* val, size_t defVal) const; + #if wxUSE_BASE64 // read a binary data block bool Read(const wxString& key, wxMemoryBuffer* data) const diff --git a/interface/wx/config.h b/interface/wx/config.h index 6d579480c0..4c3f71dae5 100644 --- a/interface/wx/config.h +++ b/interface/wx/config.h @@ -571,7 +571,29 @@ public: @endWxPerlOnly */ bool Read(const wxString& key, wxLongLong_t* ll, - wxLongLong_t defaultVal) const; + /** + Reads a size_t value, returning @true if the value was found. + If the value was not found, @a value is not changed. + + @since 3.1.5 + + @beginWxPerlOnly + Not supported by wxPerl. + @endWxPerlOnly + */ + bool Read(const wxString& key, size_t* value) const; + /** + Reads a size_t value, returning @true if the value was found. + If the value was not found, @a defaultVal is used instead. + + @since 3.1.5 + + @beginWxPerlOnly + Not supported by wxPerl. + @endWxPerlOnly + */ + bool Read(const wxString& key, size_t* value, + size_t defaultVal) const; /** Reads a double value, returning @true if the value was found. If the value was not found, @a d is not changed. diff --git a/src/common/config.cpp b/src/common/config.cpp index 22ff3fa5d1..93d6442d2d 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -177,6 +177,40 @@ bool wxConfigBase::Read(const wxString& key, int *pi, int defVal) const return r; } +// size_t is stored either as long or long long (Win64) +#if SIZEOF_SIZE_T == SIZEOF_LONG + typedef long SizeSameSizeAsSizeT; +#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG + typedef wxLongLong_t SizeSameSizeAsSizeT; +#else + #error Unexpected sizeof(size_t) +#endif + +bool wxConfigBase::Read(const wxString& key, size_t* val) const +{ + wxCHECK_MSG( val, false, wxT("wxConfig::Read(): NULL parameter") ); + + SizeSameSizeAsSizeT tmp; + if ( !Read(key, &tmp) ) + return false; + + *val = static_cast(tmp); + return true; +} + +bool wxConfigBase::Read(const wxString& key, size_t* val, size_t defVal) const +{ + wxCHECK_MSG( val, false, wxT("wxConfig::Read(): NULL parameter") ); + + if ( !Read(key, val) ) + { + *val = defVal; + return false; + } + + return true; +} + // Read floats as doubles then just type cast it down. bool wxConfigBase::Read(const wxString& key, float* val) const { diff --git a/tests/config/config.cpp b/tests/config/config.cpp index 1b60d1ccdd..e5f13d03a8 100644 --- a/tests/config/config.cpp +++ b/tests/config/config.cpp @@ -53,6 +53,7 @@ TEST_CASE("wxConfig::ReadWriteLocal", "[config]") const wxULongLong_t uval64 = wxULL(0x9000000000000009); config->Write("ull", uval64); + config->Write("size", size_t(UINT_MAX)); #ifdef wxHAS_CONFIG_TEMPLATE_RW config->Write("color1", wxColour(11,22,33,44)); #endif // wxHAS_CONFIG_TEMPLATE_RW @@ -110,6 +111,10 @@ TEST_CASE("wxConfig::ReadWriteLocal", "[config]") CHECK( ll == static_cast(uval64) ); CHECK( config->ReadLongLong("ull", 0) == static_cast(uval64) ); + size_t size; + CHECK( config->Read("size", &size) ); + CHECK( size == UINT_MAX ); + #ifdef wxHAS_CONFIG_TEMPLATE_RW wxColour color1; r = config->Read("color1", &color1); From e667071416b82464c2fc0593c91317b0ab93f33a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 13 Mar 2021 14:18:31 +0100 Subject: [PATCH 8/8] Compile wxConfig unit tests as part of non-GUI test too Almost none of the tests require GUI, so make it possible to run them without it, but still include the GUI tests when using GUI. --- tests/Makefile.in | 4 ++++ tests/config/config.cpp | 28 +++++++++++++++++++--------- tests/makefile.gcc | 4 ++++ tests/makefile.vc | 4 ++++ tests/test.bkl | 4 ++++ tests/test.vcxproj | 3 ++- tests/test.vcxproj.filters | 5 ++++- tests/test_vc7_test.vcproj | 3 +++ tests/test_vc8_test.vcproj | 4 ++++ tests/test_vc9_test.vcproj | 4 ++++ 10 files changed, 52 insertions(+), 11 deletions(-) diff --git a/tests/Makefile.in b/tests/Makefile.in index 4d6503fbe3..569f6523cd 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -68,6 +68,7 @@ TEST_OBJECTS = \ test_arrays.o \ test_base64.o \ test_cmdlinetest.o \ + test_config.o \ test_fileconf.o \ test_regconf.o \ test_datetimetest.o \ @@ -611,6 +612,9 @@ test_base64.o: $(srcdir)/base64/base64.cpp $(TEST_ODEP) test_cmdlinetest.o: $(srcdir)/cmdline/cmdlinetest.cpp $(TEST_ODEP) $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/cmdline/cmdlinetest.cpp +test_config.o: $(srcdir)/config/config.cpp $(TEST_ODEP) + $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/config/config.cpp + test_fileconf.o: $(srcdir)/config/fileconf.cpp $(TEST_ODEP) $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/config/fileconf.cpp diff --git a/tests/config/config.cpp b/tests/config/config.cpp index e5f13d03a8..a38bc920dd 100644 --- a/tests/config/config.cpp +++ b/tests/config/config.cpp @@ -6,8 +6,9 @@ // Copyright: (c) 2007 Marcin Wojdyr /////////////////////////////////////////////////////////////////////////////// -// NOTE: this test is compiled in test_gui because it uses wxColour for -// its testing purpose. +// NOTE: this test is compiled both as part of the non-GUI test and test_gui +// because it can only use wxColour in the latter. +// // See also tests/config/fileconf.cpp for wxFileConfig specific tests and // tests/config/regconf.cpp for wxRegConfig specific tests. @@ -25,9 +26,18 @@ #endif // WX_PRECOMP #include "wx/config.h" -#include "wx/colour.h" #include "wx/scopedptr.h" +// Tests using wxColour can only be done when using GUI library and they +// require template functions that are not supported by some ancient compilers. +#if wxUSE_GUI && defined(wxHAS_CONFIG_TEMPLATE_RW) + #define TEST_WXCOLOUR +#endif + +#ifdef TEST_WXCOLOUR + #include "wx/colour.h" +#endif + // -------------------------------------------------------------------------- // the tests // -------------------------------------------------------------------------- @@ -54,9 +64,9 @@ TEST_CASE("wxConfig::ReadWriteLocal", "[config]") config->Write("ull", uval64); config->Write("size", size_t(UINT_MAX)); -#ifdef wxHAS_CONFIG_TEMPLATE_RW +#ifdef TEST_WXCOLOUR config->Write("color1", wxColour(11,22,33,44)); -#endif // wxHAS_CONFIG_TEMPLATE_RW +#endif // TEST_WXCOLOUR config->Flush(); config.reset(new wxConfig(app, vendor, "", "", @@ -115,14 +125,14 @@ TEST_CASE("wxConfig::ReadWriteLocal", "[config]") CHECK( config->Read("size", &size) ); CHECK( size == UINT_MAX ); -#ifdef wxHAS_CONFIG_TEMPLATE_RW +#ifdef TEST_WXCOLOUR wxColour color1; r = config->Read("color1", &color1); CHECK( r ); CHECK( color1 == wxColour(11,22,33,44) ); CHECK( config->ReadObject("color1", wxNullColour) == color1 ); -#endif // wxHAS_CONFIG_TEMPLATE_RW +#endif // TEST_WXCOLOUR config->DeleteAll(); } @@ -174,12 +184,12 @@ size_t ReadValues(const wxConfig& config, bool has_values) CHECK( r == has_values ); read++; -#ifdef wxHAS_CONFIG_TEMPLATE_RW +#ifdef TEST_WXCOLOUR wxColour color1; r = config.Read("color1", &color1, wxColour(11,22,33,44)); CHECK( r == has_values ); read++; -#endif // wxHAS_CONFIG_TEMPLATE_RW +#endif // TEST_WXCOLOUR return read; } diff --git a/tests/makefile.gcc b/tests/makefile.gcc index 5671d8b2d1..2235e73821 100644 --- a/tests/makefile.gcc +++ b/tests/makefile.gcc @@ -38,6 +38,7 @@ TEST_OBJECTS = \ $(OBJS)\test_arrays.o \ $(OBJS)\test_base64.o \ $(OBJS)\test_cmdlinetest.o \ + $(OBJS)\test_config.o \ $(OBJS)\test_fileconf.o \ $(OBJS)\test_regconf.o \ $(OBJS)\test_datetimetest.o \ @@ -590,6 +591,9 @@ $(OBJS)\test_base64.o: ./base64/base64.cpp $(OBJS)\test_cmdlinetest.o: ./cmdline/cmdlinetest.cpp $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\test_config.o: ./config/config.cpp + $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\test_fileconf.o: ./config/fileconf.cpp $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< diff --git a/tests/makefile.vc b/tests/makefile.vc index d819e71170..31543679c3 100644 --- a/tests/makefile.vc +++ b/tests/makefile.vc @@ -41,6 +41,7 @@ TEST_OBJECTS = \ $(OBJS)\test_arrays.obj \ $(OBJS)\test_base64.obj \ $(OBJS)\test_cmdlinetest.obj \ + $(OBJS)\test_config.obj \ $(OBJS)\test_fileconf.obj \ $(OBJS)\test_regconf.obj \ $(OBJS)\test_datetimetest.obj \ @@ -1024,6 +1025,9 @@ $(OBJS)\test_base64.obj: .\base64\base64.cpp $(OBJS)\test_cmdlinetest.obj: .\cmdline\cmdlinetest.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\cmdline\cmdlinetest.cpp +$(OBJS)\test_config.obj: .\config\config.cpp + $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\config\config.cpp + $(OBJS)\test_fileconf.obj: .\config\fileconf.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\config\fileconf.cpp diff --git a/tests/test.bkl b/tests/test.bkl index 46647e4213..df402f68dc 100644 --- a/tests/test.bkl +++ b/tests/test.bkl @@ -34,6 +34,7 @@ arrays/arrays.cpp base64/base64.cpp cmdline/cmdlinetest.cpp + config/config.cpp config/fileconf.cpp config/regconf.cpp datetime/datetimetest.cpp @@ -187,6 +188,9 @@ graphics/graphmatrix.cpp graphics/graphpath.cpp graphics/imagelist.cpp + config/config.cpp controls/auitest.cpp controls/bitmapcomboboxtest.cpp diff --git a/tests/test.vcxproj b/tests/test.vcxproj index ab71189ad2..66ad910c71 100644 --- a/tests/test.vcxproj +++ b/tests/test.vcxproj @@ -478,6 +478,7 @@ + @@ -571,4 +572,4 @@ - \ No newline at end of file + diff --git a/tests/test.vcxproj.filters b/tests/test.vcxproj.filters index e285713fbf..ca3ec7b4bb 100644 --- a/tests/test.vcxproj.filters +++ b/tests/test.vcxproj.filters @@ -70,6 +70,9 @@ Source Files + + Source Files + Source Files @@ -269,4 +272,4 @@ Source Files - \ No newline at end of file + diff --git a/tests/test_vc7_test.vcproj b/tests/test_vc7_test.vcproj index ad729621a2..c73e715c7e 100644 --- a/tests/test_vc7_test.vcproj +++ b/tests/test_vc7_test.vcproj @@ -313,6 +313,9 @@ + + diff --git a/tests/test_vc8_test.vcproj b/tests/test_vc8_test.vcproj index 46d3829bcd..225e702031 100644 --- a/tests/test_vc8_test.vcproj +++ b/tests/test_vc8_test.vcproj @@ -854,6 +854,10 @@ RelativePath=".\cmdline\cmdlinetest.cpp" > + + diff --git a/tests/test_vc9_test.vcproj b/tests/test_vc9_test.vcproj index 724a21da2f..55d584019a 100644 --- a/tests/test_vc9_test.vcproj +++ b/tests/test_vc9_test.vcproj @@ -826,6 +826,10 @@ RelativePath=".\cmdline\cmdlinetest.cpp" > + +