void StopWatchTestCase::RestartBug() { wxStopWatch sw; sw.Pause(); // Calling Start() should resume the stopwatch if it was paused. static const int offset = 5000; sw.Start(offset); wxMilliSleep(sleepTime); long t = sw.Time(); WX_ASSERT_MESSAGE ( ("Actual time value is %ld", t), t >= offset + sleepTime - tolerance ); // As above, this is not actually due to the fact of the test being // automatic but just because buildot machines are usually pretty slow, so // this test often fails there simply because of the high load on them. if ( !IsAutomaticTest() ) { WX_ASSERT_MESSAGE ( ("Actual time value is %ld", t), t < offset + sleepTime + tolerance ); } }
void StopWatchTestCase::Misc() { // Buildbot machines are quite slow and sleep doesn't work reliably there, // i.e. it can sleep for much longer than requested. This is not really an // error, so just don't run this test there -- and if you get failures in // this test when running it interactively, this might also be normal if // the machine is under heavy load. if ( IsAutomaticTest() ) return; wxStopWatch sw; long t; wxLongLong usec; sw.Pause(); // pause it immediately // verify that almost no time elapsed usec = sw.TimeInMicro(); WX_ASSERT_MESSAGE ( ("Elapsed time was %" wxLongLongFmtSpec "dus", usec), usec < tolerance*1000 ); wxSleep(1); t = sw.Time(); // check that the stop watch doesn't advance while paused WX_ASSERT_MESSAGE ( ("Actual time value is %ld", t), t >= 0 && t < tolerance ); sw.Resume(); wxMilliSleep(sleepTime); t = sw.Time(); // check that it did advance now by ~1.5s WX_ASSERT_MESSAGE ( ("Actual time value is %ld", t), t > sleepTime - tolerance && t < 2*sleepTime ); sw.Pause(); // check that this sleep won't be taken into account below wxMilliSleep(sleepTime); sw.Resume(); wxMilliSleep(sleepTime); t = sw.Time(); // and it should advance again WX_ASSERT_MESSAGE ( ("Actual time value is %ld", t), t > 2*sleepTime - tolerance && t < 3*sleepTime ); }
// test parsing dates in free format void DateTimeTestCase::TestDateParse() { static const struct ParseTestData { const char *str; Date date; // NB: this should be in UTC bool good; } parseTestDates[] = { { "21 Mar 2006", { 21, wxDateTime::Mar, 2006 }, true }, { "29 Feb 1976", { 29, wxDateTime::Feb, 1976 }, true }, { "Feb 29 1976", { 29, wxDateTime::Feb, 1976 }, true }, { "31/03/06", { 31, wxDateTime::Mar, 6 }, true }, { "31/03/2006", { 31, wxDateTime::Mar, 2006 }, true }, // some invalid ones too { "29 Feb 2006" }, { "31/04/06" }, { "bloordyblop" }, { "2 . . " }, }; // special cases wxDateTime dt; CPPUNIT_ASSERT( dt.ParseDate(wxT("today")) ); CPPUNIT_ASSERT_EQUAL( wxDateTime::Today(), dt ); for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ ) { const wxString datestr = TranslateDate(parseTestDates[n].str); const char * const end = dt.ParseDate(datestr); if ( end && !*end ) { WX_ASSERT_MESSAGE( ("Erroneously parsed \"%s\"", datestr), parseTestDates[n].good ); CPPUNIT_ASSERT_EQUAL( parseTestDates[n].date.DT(), dt ); } else // failed to parse { WX_ASSERT_MESSAGE( ("Failed to parse \"%s\"", datestr), !parseTestDates[n].good ); } } // Check that incomplete parse works correctly. const char* p = dt.ParseFormat("2012-03-23 12:34:56", "%Y-%m-%d"); CPPUNIT_ASSERT_EQUAL( " 12:34:56", wxString(p) ); }
void FontTestCase::NativeFontInfo() { unsigned numFonts; const wxFont *pf = GetTestFonts(numFonts); for ( size_t n = 0; n < numFonts; n++ ) { wxFont test(*pf++); const wxString& nid = test.GetNativeFontInfoDesc(); CPPUNIT_ASSERT( !nid.empty() ); // documented to be never empty wxFont temp; CPPUNIT_ASSERT( temp.SetNativeFontInfo(nid) ); CPPUNIT_ASSERT( temp.IsOk() ); WX_ASSERT_MESSAGE( ("Test #%lu failed\ndump of test font: \"%s\"\ndump of temp font: \"%s\"", \ n, DumpFont(&test), DumpFont(&temp)), temp == test ); } // test that clearly invalid font info strings do not work wxFont font; CPPUNIT_ASSERT( !font.SetNativeFontInfo("") ); // pango_font_description_from_string() used by wxFont in wxGTK and wxX11 // never returns an error at all so this assertion fails there -- and as it // doesn't seem to be possible to do anything about it maybe we should // change wxMSW and other ports to also accept any strings? #if !defined(__WXGTK__) && !defined(__WXX11__) CPPUNIT_ASSERT( !font.SetNativeFontInfo("bloordyblop") ); #endif }
void GraphicsContextDrawingTestCase::RunIndividualDrawingCase ( DrawingTestGCFactory& gcFactory, const DrawingTestCase & testCase) { wxFileName fileName, refFileName; wxString testsOutputDirectory = wxStandardPaths::Get().GetTempDir(); wxString refOutputDirectory = GetTestsReferenceDirectory(); wxString platformTag; if (!testCase.platformIndependent && !gcFactory.PlatformIndependent()) platformTag = wxString::Format("_%s", GetPlatformTag()); fileName.Assign (testsOutputDirectory, wxString::Format("image_test_%s%s_%d", gcFactory.GetIdForFileName(), platformTag, testCase.caseNumber), gcFactory.GetExtensionForFileName()); refFileName.Assign (refOutputDirectory, wxString::Format("image_test_%s%s_%d_ref", gcFactory.GetIdForFileName(), platformTag, testCase.caseNumber), gcFactory.GetExtensionForFileName()); { wxGraphicsContext *gc = NULL; wxON_BLOCK_EXIT_OBJ1(gcFactory, DrawingTestGCFactory::CleanUp, gc); gc = gcFactory.BuildNewContext( wxSize(testCase.width, testCase.height), testCase.pointsPerInch, fileName); (this->*testCase.m_drawingF)(gc); gcFactory.SaveBuiltContext(gc); } if (GetBuildReference()) { WX_ASSERT_MESSAGE( ("Cannot copy file \"%s\" to \"%s\".", fileName.GetFullPath(), refFileName.GetFullPath()), wxCopyFile (fileName.GetFullPath(), refFileName.GetFullPath(), true)); } else if (gcFactory.UseImageComparison()) { WX_ASSERT_SAME_AS_IMAGE_FILE(fileName.GetFullPath(), refFileName.GetFullPath()); } else { WX_ASSERT_SAME_AS_FILE(fileName.GetFullPath(), refFileName.GetFullPath()); } }
virtual bool AfterWait() { // fail if still no events WX_ASSERT_MESSAGE ( ("No events during %d seconds!", static_cast<int>(WAIT_DURATION)), tested ); return true; }
void LogTestCase::SysError() { wxString s; wxLogSysError(17, "Error"); CPPUNIT_ASSERT( m_log->GetLog(wxLOG_Error).StartsWith("Error (", &s) ); WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s), s.StartsWith("error 17") ); // The last error code seems to be set somewhere in MinGW CRT as its value // is just not what we expect (ERROR_INVALID_PARAMETER instead of 0 and 0 // instead of ERROR_FILE_NOT_FOUND) so exclude the tests which rely on last // error being preserved for this compiler. #ifndef __MINGW32__ wxLogSysError("Success"); CPPUNIT_ASSERT( m_log->GetLog(wxLOG_Error).StartsWith("Success (", &s) ); WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s), s.StartsWith("error 0") ); wxOpen("no-such-file", 0, 0); wxLogSysError("Not found"); CPPUNIT_ASSERT( m_log->GetLog(wxLOG_Error).StartsWith("Not found (", &s) ); WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s), s.StartsWith("error 2") ); #endif // __MINGW32__ }
void LogTestCase::SysError() { wxString s; wxLogSysError(17, "Error"); CPPUNIT_ASSERT( m_log->GetLog(wxLOG_Error).StartsWith("Error (", &s) ); WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s), s.StartsWith("error 17") ); // Try to ensure that the system error is 0. #ifdef __WINDOWS__ ::SetLastError(0); #else errno = 0; #endif wxLogSysError("Success"); CPPUNIT_ASSERT( m_log->GetLog(wxLOG_Error).StartsWith("Success (", &s) ); WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s), s.StartsWith("error 0") ); wxOpen("no-such-file", 0, 0); wxLogSysError("Not found"); CPPUNIT_ASSERT( m_log->GetLog(wxLOG_Error).StartsWith("Not found (", &s) ); WX_ASSERT_MESSAGE( ("Error message is \"(%s\"", s), s.StartsWith("error 2") ); }
void StopWatchTestCase::RestartBug() { wxStopWatch sw; sw.Pause(); // Calling Start() should resume the stopwatch if it was paused. static const int offset = 5000; sw.Start(offset); wxMilliSleep(sleepTime); long t = sw.Time(); WX_ASSERT_MESSAGE ( ("Actual time value is %ld", t), t > offset + sleepTime - tolerance && t < offset + sleepTime + tolerance ); }
void FontTestCase::NativeFontInfoUserDesc() { unsigned numFonts; const wxFont *pf = GetTestFonts(numFonts); for ( size_t n = 0; n < numFonts; n++ ) { wxFont test(*pf++); const wxString& niud = test.GetNativeFontInfoUserDesc(); CPPUNIT_ASSERT( !niud.empty() ); // documented to be never empty wxFont temp2; CPPUNIT_ASSERT( temp2.SetNativeFontInfoUserDesc(niud) ); CPPUNIT_ASSERT( temp2.IsOk() ); #ifdef __WXGTK__ // Pango saves/restores all font info in the user-friendly string: WX_ASSERT_MESSAGE( ("Test #%lu failed; native info user desc was \"%s\" for test and \"%s\" for temp2", \ n, niud, temp2.GetNativeFontInfoUserDesc()), temp2 == test ); #else // NOTE: as documented GetNativeFontInfoUserDesc/SetNativeFontInfoUserDesc // are not granted to save/restore all font info. // In fact e.g. the font family is not saved at all; test only those // info which GetNativeFontInfoUserDesc() does indeed save: CPPUNIT_ASSERT_EQUAL( test.GetWeight(), temp2.GetWeight() ); CPPUNIT_ASSERT_EQUAL( test.GetStyle(), temp2.GetStyle() ); // if the original face name was empty, it means that any face name (in // this family) can be used for the new font so we shouldn't be // surprised to find that they differ in this case const wxString facename = test.GetFaceName(); if ( !facename.empty() ) { CPPUNIT_ASSERT_EQUAL( facename.Upper(), temp2.GetFaceName().Upper() ); } CPPUNIT_ASSERT_EQUAL( test.GetPointSize(), temp2.GetPointSize() ); CPPUNIT_ASSERT_EQUAL( test.GetEncoding(), temp2.GetEncoding() ); #endif } }
void SettingsTestCase::GlobalFonts() { const wxFont font[] = { *wxNORMAL_FONT, *wxSMALL_FONT, *wxITALIC_FONT, *wxSWISS_FONT }; for (unsigned int i=0; i < WXSIZEOF(font); i++) { CPPUNIT_ASSERT( font[i].IsOk() ); const wxString facename = font[i].GetFaceName(); if ( !facename.empty() ) { WX_ASSERT_MESSAGE( ("font #%u: facename \"%s\" is invalid", i, facename), wxFontEnumerator::IsValidFacename(facename) ); } } }
void FileNameTestCase::TestReplace() { static const struct FileNameTest { const char *original; const char *env_contents; const char *replace_fmtstring; const char *expected; wxPathFormat fmt; } tests[] = { { "/usr/a/strange path/lib/someFile.ext", "/usr/a/strange path", "$%s", "$TEST_VAR/lib/someFile.ext", wxPATH_UNIX }, { "/usr/a/path/lib/someFile.ext", "/usr/a/path", "$%s", "$TEST_VAR/lib/someFile.ext", wxPATH_UNIX }, { "/usr/a/path/lib/someFile", "/usr/a/path/", "$%s", "$TEST_VARlib/someFile", wxPATH_UNIX }, { "/usr/a/path/lib/", "/usr/a/path/", "$(%s)", "$(TEST_VAR)lib/", wxPATH_UNIX }, { "/usr/a/path/lib/", "/usr/a/path/", "${{%s}}", "${{TEST_VAR}}lib/", wxPATH_UNIX }, { "/usr/a/path/lib/", "/usr/a/path/", "%s", "TEST_VARlib/", wxPATH_UNIX }, { "/usr/a/path/lib/", "/usr/a/path/", "%s//", "TEST_VAR/lib/", wxPATH_UNIX }, // note: empty directory components are automatically removed by wxFileName thus // using // in the replace format string has no effect { "/usr/../a/path/lib/", "/usr/a/path/", "%s", "/usr/../a/path/lib/", wxPATH_UNIX }, { "/usr/a/path/usr/usr", "/usr", "%s", "TEST_VAR/a/pathTEST_VAR/usr", wxPATH_UNIX }, { "/usr/a/path/usr/usr", "/usr", "$%s", "$TEST_VAR/a/path$TEST_VAR/usr", wxPATH_UNIX }, { "/a/b/c/d", "a/", "%s", "/TEST_VARb/c/d", wxPATH_UNIX }, { "C:\\A\\Strange Path\\lib\\someFile", "C:\\A\\Strange Path", "%%%s%%", "%TEST_VAR%\\lib\\someFile", wxPATH_WIN }, { "C:\\A\\Path\\lib\\someFile", "C:\\A\\Path", "%%%s%%", "%TEST_VAR%\\lib\\someFile", wxPATH_WIN }, { "C:\\A\\Path\\lib\\someFile", "C:\\A\\Path", "$(%s)", "$(TEST_VAR)\\lib\\someFile", wxPATH_WIN } }; for ( size_t i = 0; i < WXSIZEOF(tests); i++ ) { const FileNameTest& fnt = tests[i]; wxFileName fn(fnt.original, fnt.fmt); // set the environment variable wxSetEnv("TEST_VAR", fnt.env_contents); // be sure this ReplaceEnvVariable does not fail WX_ASSERT_MESSAGE ( ("#%d: ReplaceEnvVariable(%s) failed", (int)i, fnt.replace_fmtstring), fn.ReplaceEnvVariable("TEST_VAR", fnt.replace_fmtstring, fnt.fmt) ); // compare result with expected string wxString expected(fnt.expected); WX_ASSERT_EQUAL_MESSAGE ( ("array element #%d", (int)i), expected, fn.GetFullPath(fnt.fmt) ); } // now test ReplaceHomeDir wxFileName fn = wxFileName::DirName(wxGetHomeDir()); fn.AppendDir("test1"); fn.AppendDir("test2"); fn.AppendDir("test3"); fn.SetName("some file"); WX_ASSERT_MESSAGE ( ("ReplaceHomeDir(%s) failed", fn.GetFullPath()), fn.ReplaceHomeDir() ); CPPUNIT_ASSERT_EQUAL( wxString("~/test1/test2/test3/some file"), fn.GetFullPath(wxPATH_UNIX) ); }
void FileNameTestCase::TestNormalize() { // prepare some data to be used later wxString sep = wxFileName::GetPathSeparator(); wxString cwd = wxGetCwd(); wxString home = wxGetUserHome(); cwd.Replace(sep, wxT("/")); if (cwd.Last() != wxT('/')) cwd += wxT('/'); home.Replace(sep, wxT("/")); if (home.Last() != wxT('/')) home += wxT('/'); // since we will always be testing paths using the wxPATH_UNIX // format, we need to remove the volume, if present if (home.Contains(wxT(':'))) home = home.AfterFirst(wxT(':')); if (cwd.Contains(wxT(':'))) cwd = cwd.AfterFirst(wxT(':')); static const struct FileNameTest { const char *original; int flags; const char *expected; wxPathFormat fmt; } tests[] = { // test wxPATH_NORM_ENV_VARS #ifdef __WINDOWS__ { "%ABCDEF%/g/h/i", wxPATH_NORM_ENV_VARS, "abcdef/g/h/i", wxPATH_UNIX }, #else { "$(ABCDEF)/g/h/i", wxPATH_NORM_ENV_VARS, "abcdef/g/h/i", wxPATH_UNIX }, #endif // test wxPATH_NORM_DOTS { "a/.././b/c/../../", wxPATH_NORM_DOTS, "", wxPATH_UNIX }, { "", wxPATH_NORM_DOTS, "", wxPATH_UNIX }, { "./foo", wxPATH_NORM_DOTS, "foo", wxPATH_UNIX }, { "b/../bar", wxPATH_NORM_DOTS, "bar", wxPATH_UNIX }, { "c/../../quux", wxPATH_NORM_DOTS, "../quux", wxPATH_UNIX }, { "/c/../../quux", wxPATH_NORM_DOTS, "/quux", wxPATH_UNIX }, // test wxPATH_NORM_TILDE: notice that ~ is only interpreted specially // when it is the first character in the file name { "/a/b/~", wxPATH_NORM_TILDE, "/a/b/~", wxPATH_UNIX }, { "/~/a/b", wxPATH_NORM_TILDE, "/~/a/b", wxPATH_UNIX }, { "~/a/b", wxPATH_NORM_TILDE, "HOME/a/b", wxPATH_UNIX }, // test wxPATH_NORM_CASE { "Foo", wxPATH_NORM_CASE, "Foo", wxPATH_UNIX }, { "Foo", wxPATH_NORM_CASE, "foo", wxPATH_DOS }, { "C:\\Program Files\\wx", wxPATH_NORM_CASE, "c:\\program files\\wx", wxPATH_DOS }, { "C:/Program Files/wx", wxPATH_NORM_ALL | wxPATH_NORM_CASE, "c:\\program files\\wx", wxPATH_DOS }, { "C:\\Users\\zeitlin", wxPATH_NORM_ALL | wxPATH_NORM_CASE, "c:\\users\\zeitlin", wxPATH_DOS }, // test wxPATH_NORM_ABSOLUTE { "a/b/", wxPATH_NORM_ABSOLUTE, "CWD/a/b/", wxPATH_UNIX }, { "a/b/c.ext", wxPATH_NORM_ABSOLUTE, "CWD/a/b/c.ext", wxPATH_UNIX }, { "/a", wxPATH_NORM_ABSOLUTE, "/a", wxPATH_UNIX }, // test giving no flags at all to Normalize() { "a/b/", 0, "a/b/", wxPATH_UNIX }, { "a/b/c.ext", 0, "a/b/c.ext", wxPATH_UNIX }, { "/a", 0, "/a", wxPATH_UNIX }, // test handling dots without wxPATH_NORM_DOTS and wxPATH_NORM_ABSOLUTE // for both existing and non-existent files (this is important under // MSW where GetLongPathName() works only for the former) { "./foo", wxPATH_NORM_LONG, "./foo", wxPATH_UNIX }, { "../foo", wxPATH_NORM_LONG, "../foo", wxPATH_UNIX }, { ".\\test.bkl", wxPATH_NORM_LONG, ".\\test.bkl", wxPATH_DOS }, { ".\\foo", wxPATH_NORM_LONG, ".\\foo", wxPATH_DOS }, { "..\\Makefile.in", wxPATH_NORM_LONG, "..\\Makefile.in", wxPATH_DOS }, { "..\\foo", wxPATH_NORM_LONG, "..\\foo", wxPATH_DOS }, }; // set the env var ABCDEF wxSetEnv("ABCDEF", "abcdef"); for ( size_t i = 0; i < WXSIZEOF(tests); i++ ) { const FileNameTest& fnt = tests[i]; wxFileName fn(fnt.original, fnt.fmt); // be sure this normalization does not fail WX_ASSERT_MESSAGE ( ("#%d: Normalize(%s) failed", (int)i, fnt.original), fn.Normalize(fnt.flags, cwd, fnt.fmt) ); // compare result with expected string wxString expected(tests[i].expected); expected.Replace("HOME/", home); expected.Replace("CWD/", cwd); WX_ASSERT_EQUAL_MESSAGE ( ("array element #%d", (int)i), expected, fn.GetFullPath(fnt.fmt) ); } // MSW-only test for wxPATH_NORM_LONG: notice that we only run it if short // names generation is not disabled for this system as otherwise the file // MKINST~1 doesn't exist at all and normalizing it fails (it's possible // that we're on a FAT partition in which case the test would still succeed // and also that the registry key was changed recently and didn't take // effect yet but these are marginal cases which we consciously choose to // ignore for now) #ifdef __WINDOWS__ long shortNamesDisabled; if ( wxRegKey ( wxRegKey::HKLM, "SYSTEM\\CurrentControlSet\\Control\\FileSystem" ).QueryValue("NtfsDisable8dot3NameCreation", &shortNamesDisabled) && !shortNamesDisabled ) { wxFileName fn("..\\MKINST~1"); CPPUNIT_ASSERT( fn.Normalize(wxPATH_NORM_LONG, cwd) ); CPPUNIT_ASSERT_EQUAL( "..\\mkinstalldirs", fn.GetFullPath() ); } //else: when in doubt, don't run the test #endif // __WINDOWS__ }
// test parsing dates in RFC822 format void DateTimeTestCase::TestParceRFC822() { static const struct ParseTestData { const char *rfc822; Date date; // NB: this should be in UTC bool good; } parseTestDates[] = { { "Sat, 18 Dec 1999 00:46:40 +0100", { 17, wxDateTime::Dec, 1999, 23, 46, 40 }, true }, { "Wed, 1 Dec 1999 05:17:20 +0300", { 1, wxDateTime::Dec, 1999, 2, 17, 20 }, true }, { "Sun, 28 Aug 2005 03:31:30 +0200", { 28, wxDateTime::Aug, 2005, 1, 31, 30 }, true }, { "Sat, 18 Dec 1999 10:48:30 -0500", { 18, wxDateTime::Dec, 1999, 15, 48, 30 }, true }, // seconds are optional according to the RFC { "Sun, 01 Jun 2008 16:30 +0200", { 1, wxDateTime::Jun, 2008, 14, 30, 00 }, true }, // try some bogus ones too { "Sun, 01 Jun 2008 16:30: +0200", { 0 }, false }, }; for ( unsigned n = 0; n < WXSIZEOF(parseTestDates); n++ ) { const char * const datestr = parseTestDates[n].rfc822; wxDateTime dt; if ( dt.ParseRfc822Date(datestr) ) { WX_ASSERT_MESSAGE( ("Erroneously parsed \"%s\"", datestr), parseTestDates[n].good ); wxDateTime dtReal = parseTestDates[n].date.DT().FromUTC(); CPPUNIT_ASSERT_EQUAL( dtReal, dt ); } else // failed to parse { WX_ASSERT_MESSAGE( ("Failed to parse \"%s\"", datestr), !parseTestDates[n].good ); } } }
// test wxDateTime -> text conversion void DateTimeTestCase::TestTimeFormat() { // some information may be lost during conversion, so store what kind // of info should we recover after a round trip enum CompareKind { CompareNone, // don't try comparing CompareBoth, // dates and times should be identical CompareYear, // don't compare centuries (fails for 2 digit years) CompareDate, // dates only CompareTime // time only }; static const struct { CompareKind compareKind; const char *format; } formatTestFormats[] = { { CompareYear, "---> %c" }, // %c could use 2 digit years { CompareDate, "Date is %A, %d of %B, in year %Y" }, { CompareYear, "Date is %x, time is %X" }, // %x could use 2 digits { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" }, { CompareNone, "The day of year: %j, the week of year: %W" }, { CompareDate, "ISO date without separators: %Y%m%d" }, { CompareBoth, "RFC 2822 string: %Y-%m-%d %H:%M:%S.%l %z" }, }; const long timeZonesOffsets[] = { wxDateTime::TimeZone(wxDateTime::Local).GetOffset(), // Fictitious TimeZone offsets to ensure time zone formating and // interpretation works -(3600 + 2*60), 3*3600 + 30*60 }; static const Date formatTestDates[] = { { 29, wxDateTime::May, 1976, 18, 30, 00, 0.0, wxDateTime::Inv_WeekDay }, { 31, wxDateTime::Dec, 1999, 23, 30, 00, 0.0, wxDateTime::Inv_WeekDay }, { 6, wxDateTime::Feb, 1937, 23, 30, 00, 0.0, wxDateTime::Inv_WeekDay }, { 6, wxDateTime::Feb, 1856, 23, 30, 00, 0.0, wxDateTime::Inv_WeekDay }, { 6, wxDateTime::Feb, 1857, 23, 30, 00, 0.0, wxDateTime::Inv_WeekDay }, { 29, wxDateTime::May, 2076, 18, 30, 00, 0.0, wxDateTime::Inv_WeekDay }, // FIXME: the test with 02:15:25 time doesn't pass because of DST // computation problems, we get back 03:15:25 { 29, wxDateTime::Feb, 2400, 04, 15, 25, 0.0, wxDateTime::Inv_WeekDay }, #if 0 // Need to add support for BCE dates. { 01, wxDateTime::Jan, -52, 03, 16, 47, 0.0, wxDateTime::Inv_WeekDay }, #endif }; for ( unsigned idxtz = 0; idxtz < WXSIZEOF(timeZonesOffsets); ++idxtz ) { wxDateTime::TimeZone tz(timeZonesOffsets[idxtz]); const bool isLocalTz = tz.GetOffset() == -wxGetTimeZone(); for ( size_t d = 0; d < WXSIZEOF(formatTestDates); d++ ) { wxDateTime dt = formatTestDates[d].DT(); for ( unsigned n = 0; n < WXSIZEOF(formatTestFormats); n++ ) { const char *fmt = formatTestFormats[n].format; // skip the check with %p for those locales which have empty AM/PM strings: // for those locales it's impossible to pass the test with %p... wxString am, pm; wxDateTime::GetAmPmStrings(&am, &pm); if (am.empty() && pm.empty() && wxStrstr(fmt, "%p") != NULL) continue; // what can we recover? CompareKind kind = formatTestFormats[n].compareKind; // When using a different time zone we must perform a time zone // conversion below which doesn't always work correctly, check // for the cases when it doesn't. if ( !isLocalTz ) { // DST computation doesn't work correctly for dates above // 2038 currently on the systems with 32 bit time_t. if ( dt.GetYear() >= 2038 ) continue; // We can't compare just dates nor just times when doing TZ // conversion as both are affected by the DST: for the // dates, the DST can switch midnight to 23:00 of the // previous day while for the times DST can be different // for the original date and today. if ( kind == CompareDate || kind == CompareTime ) continue; } // do convert date to string wxString s = dt.Format(fmt, tz); // convert back wxDateTime dt2; const char *result = dt2.ParseFormat(s, fmt); if ( !result ) { // conversion failed - should it have? WX_ASSERT_MESSAGE( ("Test #%u failed: failed to parse \"%s\"", n, s), kind == CompareNone ); } else // conversion succeeded { // currently ParseFormat() doesn't support "%Z" and so is // incapable of parsing time zone part used at the end of date // representations in many (but not "C") locales, compensate // for it ourselves by simply consuming and ignoring it while ( *result && (*result >= 'A' && *result <= 'Z') ) result++; WX_ASSERT_MESSAGE( ("Test #%u failed: \"%s\" was left unparsed in \"%s\"", n, result, s), !*result ); // Without "%z" we can't recover the time zone used in the // call to Format() so we need to call MakeFromTimezone() // explicitly. if ( !strstr(fmt, "%z") && !isLocalTz ) dt2.MakeFromTimezone(tz); switch ( kind ) { case CompareYear: if ( dt2.GetCentury() != dt.GetCentury() ) { CPPUNIT_ASSERT_EQUAL(dt.GetYear() % 100, dt2.GetYear() % 100); dt2.SetYear(dt.GetYear()); } // fall through and compare everything case CompareBoth: CPPUNIT_ASSERT_EQUAL( dt, dt2 ); break; case CompareDate: CPPUNIT_ASSERT( dt.IsSameDate(dt2) ); break; case CompareTime: CPPUNIT_ASSERT( dt.IsSameTime(dt2) ); break; case CompareNone: wxFAIL_MSG( wxT("unexpected") ); break; } } } } } wxDateTime dt; #if 0 // special case which was known to fail CPPUNIT_ASSERT( dt.ParseFormat("02/06/1856", "%x") ); CPPUNIT_ASSERT_EQUAL( 1856, dt.GetYear() ); #endif // also test %l separately CPPUNIT_ASSERT( dt.ParseFormat("12:23:45.678", "%H:%M:%S.%l") ); CPPUNIT_ASSERT_EQUAL( 678, dt.GetMillisecond() ); // test special case of %l matching 0 milliseconds CPPUNIT_ASSERT( dt.ParseFormat("12:23:45.000", "%H:%M:%S.%l") ); CPPUNIT_ASSERT_EQUAL( 0, dt.GetMillisecond() ); // test partially specified dates too wxDateTime dtDef(26, wxDateTime::Sep, 2008); CPPUNIT_ASSERT( dt.ParseFormat("17", "%d") ); CPPUNIT_ASSERT_EQUAL( 17, dt.GetDay() ); // test some degenerate cases CPPUNIT_ASSERT( !dt.ParseFormat("", "%z") ); CPPUNIT_ASSERT( !dt.ParseFormat("", "%%") ); // test compilation of some calls which should compile (and not result in // ambiguity because of char*<->wxCStrData<->wxString conversions) wxString s("foo"); CPPUNIT_ASSERT( !dt.ParseFormat("foo") ); CPPUNIT_ASSERT( !dt.ParseFormat(wxT("foo")) ); CPPUNIT_ASSERT( !dt.ParseFormat(s) ); dt.ParseFormat(s.c_str()); // Simply test compilation of this one. CPPUNIT_ASSERT( !dt.ParseFormat("foo", "%c") ); CPPUNIT_ASSERT( !dt.ParseFormat(wxT("foo"), "%c") ); CPPUNIT_ASSERT( !dt.ParseFormat(s, "%c") ); dt.ParseFormat(s.c_str(), "%c"); CPPUNIT_ASSERT( !dt.ParseFormat("foo", wxT("%c")) ); CPPUNIT_ASSERT( !dt.ParseFormat(wxT("foo"), wxT("%c")) ); CPPUNIT_ASSERT( !dt.ParseFormat(s, "%c") ); dt.ParseFormat(s.c_str(), wxT("%c")); wxString spec("%c"); CPPUNIT_ASSERT( !dt.ParseFormat("foo", spec) ); CPPUNIT_ASSERT( !dt.ParseFormat(wxT("foo"), spec) ); CPPUNIT_ASSERT( !dt.ParseFormat(s, spec) ); dt.ParseFormat(s.c_str(), spec); }
void DateTimeTestCase::TestDateTimeParse() { static const struct ParseTestData { const char *str; Date date; // NB: this should be in UTC bool good; } parseTestDates[] = { { "Thu 22 Nov 2007 07:40:00 PM", { 22, wxDateTime::Nov, 2007, 19, 40, 0 }, true }, { "2010-01-04 14:30", { 4, wxDateTime::Jan, 2010, 14, 30, 0 }, true }, { "bloordyblop", { 1, wxDateTime::Jan, 9999, 0, 0, 0}, false }, { "2012-01-01 10:12:05 +0100", { 1, wxDateTime::Jan, 2012, 10, 12, 5, -1 }, false // ParseDateTime does know yet +0100 }, }; // the test strings here use "PM" which is not available in all locales so // we need to use "C" locale for them CLocaleSetter cloc; wxDateTime dt; for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ ) { const wxString datestr = TranslateDate(parseTestDates[n].str); const char * const end = dt.ParseDateTime(datestr); if ( end && !*end ) { WX_ASSERT_MESSAGE( ("Erroneously parsed \"%s\"", datestr), parseTestDates[n].good ); CPPUNIT_ASSERT_EQUAL( parseTestDates[n].date.DT(), dt ); } else // failed to parse { WX_ASSERT_MESSAGE( ("Failed to parse \"%s\"", datestr), !parseTestDates[n].good ); CPPUNIT_ASSERT( !parseTestDates[n].good ); } } }
void EllipsizationTestCase::NormalCase() { wxMemoryDC dc; static const char *stringsToTest[] = { "N", ".", "x", "foobar", "\xCE\xB1", // U03B1 (GREEK SMALL LETTER ALPHA) "Another test", "a very very very very very very very long string", // alpha+beta+gamma+delta+epsilon+zeta+eta+theta+iota "\xCE\xB1\xCE\xB2\xCE\xB3\xCE\xB4\xCE\xB5\xCE\xB6\xCE\xB7\xCE\xB8\xCE\xB9", "\t", "\t\t\t\t\t", "a\tstring\twith\ttabs", "\n", "\n\n\n\n\n", "a\nstring\nwith\nnewlines", "&", "&&&&&&&", "a&string&with&newlines", "\t\n&", "a\t\n&string\t\n&with\t\n&many\t\n&chars" }; static const int flagsToTest[] = { 0, wxELLIPSIZE_FLAGS_PROCESS_MNEMONICS, wxELLIPSIZE_FLAGS_EXPAND_TABS, wxELLIPSIZE_FLAGS_PROCESS_MNEMONICS | wxELLIPSIZE_FLAGS_EXPAND_TABS }; static const wxEllipsizeMode modesToTest[] = { wxELLIPSIZE_START, wxELLIPSIZE_MIDDLE, wxELLIPSIZE_END }; const int charWidth = dc.GetCharWidth(); int widthsToTest[] = { 6*charWidth, 10*charWidth, 15*charWidth }; for ( unsigned int s = 0; s < WXSIZEOF(stringsToTest); s++ ) { const wxString str = wxString::FromUTF8(stringsToTest[s]); for ( unsigned int f = 0; f < WXSIZEOF(flagsToTest); f++ ) { for ( unsigned int m = 0; m < WXSIZEOF(modesToTest); m++ ) { for ( unsigned int w = 0; w < WXSIZEOF(widthsToTest); w++ ) { wxString ret = wxControl::Ellipsize ( str, dc, modesToTest[m], widthsToTest[w], flagsToTest[f] ); WX_ASSERT_MESSAGE ( ( "Test #(%u,%u.%u): \"%s\" -> \"%s\"; width=%dpx > %dpx", s, f, m, str, ret, dc.GetMultiLineTextExtent(ret).GetWidth(), widthsToTest[w] ), dc.GetMultiLineTextExtent(ret).GetWidth() <= widthsToTest[w] ); } } } } }
void FontTestCase::GetSet() { unsigned numFonts; const wxFont *pf = GetTestFonts(numFonts); for ( unsigned n = 0; n < numFonts; n++ ) { wxFont test(*pf++); // remember: getters can only be called when wxFont::IsOk() == true CPPUNIT_ASSERT( test.IsOk() ); // test Get/SetFaceName() CPPUNIT_ASSERT( !test.SetFaceName("a dummy face name") ); CPPUNIT_ASSERT( !test.IsOk() ); // if the call to SetFaceName() below fails on your system/port, // consider adding another branch to this #if #if defined(__WXMSW__) || defined(__WXOSX__) static const char *knownGoodFaceName = "Arial"; #else static const char *knownGoodFaceName = "Monospace"; #endif WX_ASSERT_MESSAGE ( ("failed to set face name \"%s\" for test font #%u\n" "(this failure is harmless if this face name is not " "available on this system)", knownGoodFaceName, n), test.SetFaceName(knownGoodFaceName) ); CPPUNIT_ASSERT( test.IsOk() ); // test Get/SetFamily() test.SetFamily( wxFONTFAMILY_ROMAN ); CPPUNIT_ASSERT( test.IsOk() ); // note that there is always the possibility that GetFamily() returns // wxFONTFAMILY_DEFAULT (meaning "unknown" in this case) so that we // consider it as a valid return value const wxFontFamily family = test.GetFamily(); if ( family != wxFONTFAMILY_DEFAULT ) CPPUNIT_ASSERT_EQUAL( wxFONTFAMILY_ROMAN, family ); // test Get/SetEncoding() //test.SetEncoding( wxFONTENCODING_KOI8 ); //CPPUNIT_ASSERT( test.IsOk() ); //CPPUNIT_ASSERT_EQUAL( wxFONTENCODING_KOI8 , test.GetEncoding() ); // test Get/SetPointSize() test.SetPointSize(30); CPPUNIT_ASSERT( test.IsOk() ); CPPUNIT_ASSERT_EQUAL( 30, test.GetPointSize() ); // test Get/SetPixelSize() test.SetPixelSize(wxSize(0,30)); CPPUNIT_ASSERT( test.IsOk() ); CPPUNIT_ASSERT( test.GetPixelSize().GetHeight() <= 30 ); // NOTE: the match found by SetPixelSize() may be not 100% precise; it // only grants that a font smaller than the required height will // be selected // test Get/SetStyle() test.SetStyle(wxFONTSTYLE_SLANT); CPPUNIT_ASSERT( test.IsOk() ); #ifdef __WXMSW__ // on wxMSW wxFONTSTYLE_SLANT==wxFONTSTYLE_ITALIC CPPUNIT_ASSERT( wxFONTSTYLE_SLANT == test.GetStyle() || wxFONTSTYLE_ITALIC == test.GetStyle() ); #else CPPUNIT_ASSERT_EQUAL( wxFONTSTYLE_SLANT, test.GetStyle() ); #endif // test Get/SetUnderlined() test.SetUnderlined(true); CPPUNIT_ASSERT( test.IsOk() ); CPPUNIT_ASSERT_EQUAL( true, test.GetUnderlined() ); // test Get/SetWeight() test.SetWeight(wxFONTWEIGHT_BOLD); CPPUNIT_ASSERT( test.IsOk() ); CPPUNIT_ASSERT_EQUAL( wxFONTWEIGHT_BOLD, test.GetWeight() ); } }