From: Ryan Norton Date: Sun, 31 Oct 2004 04:41:27 +0000 (+0000) Subject: Rename some tests to avoid conflicts with project builder GUI debugger X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/a9e994615409e36d441135e4fa0761cf0398a2aa Rename some tests to avoid conflicts with project builder GUI debugger git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30194 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/tests/datetime/datetime.cpp b/tests/datetime/datetime.cpp deleted file mode 100644 index bc68b2f7cc..0000000000 --- a/tests/datetime/datetime.cpp +++ /dev/null @@ -1,679 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Name: tests/datetime/datetime.cpp -// Purpose: wxDateTime unit test -// Author: Vadim Zeitlin -// Created: 2004-06-23 (extracted from samples/console/console.cpp) -// RCS-ID: $Id$ -// Copyright: (c) 2004 Vadim Zeitlin -/////////////////////////////////////////////////////////////////////////////// - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#ifndef WX_PRECOMP -#endif // WX_PRECOMP - -#include "wx/datetime.h" - -#include "wx/cppunit.h" - -// ---------------------------------------------------------------------------- -// broken down date representation used for testing -// ---------------------------------------------------------------------------- - -struct Date -{ - wxDateTime::wxDateTime_t day; - wxDateTime::Month month; - int year; - wxDateTime::wxDateTime_t hour, min, sec; - double jdn; - wxDateTime::WeekDay wday; - time_t gmticks, ticks; - - void Init(const wxDateTime::Tm& tm) - { - day = tm.mday; - month = tm.mon; - year = tm.year; - hour = tm.hour; - min = tm.min; - sec = tm.sec; - jdn = 0.0; - gmticks = ticks = -1; - } - - wxDateTime DT() const - { return wxDateTime(day, month, year, hour, min, sec); } - - bool SameDay(const wxDateTime::Tm& tm) const - { - return day == tm.mday && month == tm.mon && year == tm.year; - } - - wxString Format() const - { - wxString s; - s.Printf(_T("%02d:%02d:%02d %10s %02d, %4d%s"), - hour, min, sec, - wxDateTime::GetMonthName(month).c_str(), - day, - abs(wxDateTime::ConvertYearToBC(year)), - year > 0 ? _T("AD") : _T("BC")); - return s; - } - - wxString FormatDate() const - { - wxString s; - s.Printf(_T("%02d-%s-%4d%s"), - day, - wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(), - abs(wxDateTime::ConvertYearToBC(year)), - year > 0 ? _T("AD") : _T("BC")); - return s; - } -}; - -// ---------------------------------------------------------------------------- -// test data -// ---------------------------------------------------------------------------- - -static const Date testDates[] = -{ - { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 }, - { 7, wxDateTime::Feb, 2036, 00, 00, 00, 2464730.5, wxDateTime::Thu, -1, -1 }, - { 8, wxDateTime::Feb, 2036, 00, 00, 00, 2464731.5, wxDateTime::Fri, -1, -1 }, - { 1, wxDateTime::Jan, 2037, 00, 00, 00, 2465059.5, wxDateTime::Thu, -1, -1 }, - { 1, wxDateTime::Jan, 2038, 00, 00, 00, 2465424.5, wxDateTime::Fri, -1, -1 }, - { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 }, - { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 }, - { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 }, - { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 }, - { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 }, - { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 }, - { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 }, - { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 }, - { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 }, - { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 }, - { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 }, - { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 }, - { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 }, - { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 }, -}; - - -// ---------------------------------------------------------------------------- -// test class -// ---------------------------------------------------------------------------- - -class DateTimeTestCase : public CppUnit::TestCase -{ -public: - DateTimeTestCase() { } - -private: - CPPUNIT_TEST_SUITE( DateTimeTestCase ); - CPPUNIT_TEST( TestLeapYears ); - CPPUNIT_TEST( TestTimeSet ); - CPPUNIT_TEST( TestTimeJDN ); - CPPUNIT_TEST( TestTimeWNumber ); - CPPUNIT_TEST( TestTimeWDays ); - CPPUNIT_TEST( TestTimeDST ); - CPPUNIT_TEST( TestTimeFormat ); - CPPUNIT_TEST( TestTimeTicks ); - CPPUNIT_TEST( TestTimeParse ); - CPPUNIT_TEST( TestTimeArithmetics ); - CPPUNIT_TEST_SUITE_END(); - - void TestLeapYears(); - void TestTimeSet(); - void TestTimeJDN(); - void TestTimeWNumber(); - void TestTimeWDays(); - void TestTimeDST(); - void TestTimeFormat(); - void TestTimeTicks(); - void TestTimeParse(); - void TestTimeArithmetics(); - - DECLARE_NO_COPY_CLASS(DateTimeTestCase) -}; - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION( DateTimeTestCase ); - -// also include in it's own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( DateTimeTestCase, "DateTimeTestCase" ); - -// ============================================================================ -// implementation -// ============================================================================ - -// test leap years detection -void DateTimeTestCase::TestLeapYears() -{ - static const struct LeapYearTestData - { - int year; - bool isLeap; - } years[] = - { - { 1900, false }, - { 1990, false }, - { 1976, true }, - { 2000, true }, - { 2030, false }, - { 1984, true }, - { 2100, false }, - { 2400, true }, - }; - - for ( size_t n = 0; n < WXSIZEOF(years); n++ ) - { - const LeapYearTestData& y = years[n]; - - CPPUNIT_ASSERT( wxDateTime::IsLeapYear(y.year) == y.isLeap ); - } -} - -// test constructing wxDateTime objects -void DateTimeTestCase::TestTimeSet() -{ - for ( size_t n = 0; n < WXSIZEOF(testDates); n++ ) - { - const Date& d1 = testDates[n]; - wxDateTime dt = d1.DT(); - - Date d2; - d2.Init(dt.GetTm()); - - wxString s1 = d1.Format(), - s2 = d2.Format(); - - CPPUNIT_ASSERT( s1 == s2 ); - } -} - -// test conversions to JDN &c -void DateTimeTestCase::TestTimeJDN() -{ - for ( size_t n = 0; n < WXSIZEOF(testDates); n++ ) - { - const Date& d = testDates[n]; - wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec); - double jdn = dt.GetJulianDayNumber(); - - CPPUNIT_ASSERT( jdn == d.jdn ); - - dt.Set(jdn); - CPPUNIT_ASSERT( dt.GetJulianDayNumber() == jdn ); - } -} - -// test week days computation -void DateTimeTestCase::TestTimeWDays() -{ - // test GetWeekDay() - size_t n; - for ( n = 0; n < WXSIZEOF(testDates); n++ ) - { - const Date& d = testDates[n]; - wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec); - - wxDateTime::WeekDay wday = dt.GetWeekDay(); - CPPUNIT_ASSERT( wday == d.wday ); - } - - // test SetToWeekDay() - struct WeekDateTestData - { - Date date; // the real date (precomputed) - int nWeek; // its week index in the month - wxDateTime::WeekDay wday; // the weekday - wxDateTime::Month month; // the month - int year; // and the year - - wxString Format() const - { - wxString s, which; - switch ( nWeek < -1 ? -nWeek : nWeek ) - { - case 1: which = _T("first"); break; - case 2: which = _T("second"); break; - case 3: which = _T("third"); break; - case 4: which = _T("fourth"); break; - case 5: which = _T("fifth"); break; - - case -1: which = _T("last"); break; - } - - if ( nWeek < -1 ) - { - which += _T(" from end"); - } - - s.Printf(_T("The %s %s of %s in %d"), - which.c_str(), - wxDateTime::GetWeekDayName(wday).c_str(), - wxDateTime::GetMonthName(month).c_str(), - year); - - return s; - } - }; - - // the array data was generated by the following python program - /* -from DateTime import * -from whrandom import * -from string import * - -monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] -wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ] - -week = DateTimeDelta(7) - -for n in range(20): - year = randint(1900, 2100) - month = randint(1, 12) - day = randint(1, 28) - dt = DateTime(year, month, day) - wday = dt.day_of_week - - countFromEnd = choice([-1, 1]) - weekNum = 0; - - while dt.month is month: - dt = dt - countFromEnd * week - weekNum = weekNum + countFromEnd - - data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] } - - print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\ - "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data - */ - - static const WeekDateTestData weekDatesTestData[] = - { - { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 }, - { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 }, - { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 }, - { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 }, - { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 }, - { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 }, - { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 }, - { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 }, - { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 }, - { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 }, - { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 }, - { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 }, - { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 }, - { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 }, - { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 }, - { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 }, - { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 }, - { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 }, - { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 }, - { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 }, - - }; - - wxDateTime dt; - for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ ) - { - const WeekDateTestData& wd = weekDatesTestData[n]; - - dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year); - - const Date& d = wd.date; - CPPUNIT_ASSERT( d.SameDay(dt.GetTm()) ); - } -} - -// test the computation of (ISO) week numbers -void DateTimeTestCase::TestTimeWNumber() -{ - struct WeekNumberTestData - { - Date date; // the date - wxDateTime::wxDateTime_t week; // the week number in the year - wxDateTime::wxDateTime_t wmon; // the week number in the month - wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun - wxDateTime::wxDateTime_t dnum; // day number in the year - }; - - // data generated with the following python script: - /* -from DateTime import * -from whrandom import * -from string import * - -monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] -wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ] - -def GetMonthWeek(dt): - weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1 - if weekNumMonth < 0: - weekNumMonth = weekNumMonth + 53 - return weekNumMonth - -def GetLastSundayBefore(dt): - if dt.iso_week[2] == 7: - return dt - else: - return dt - DateTimeDelta(dt.iso_week[2]) - -for n in range(20): - year = randint(1900, 2100) - month = randint(1, 12) - day = randint(1, 28) - dt = DateTime(year, month, day) - dayNum = dt.day_of_year - weekNum = dt.iso_week[1] - weekNumMonth = GetMonthWeek(dt) - - weekNumMonth2 = 0 - dtSunday = GetLastSundayBefore(dt) - - while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)): - weekNumMonth2 = weekNumMonth2 + 1 - dtSunday = dtSunday - DateTimeDelta(7) - - data = { 'day': rjust(`day`, 2), \ - 'month': monthNames[month - 1], \ - 'year': year, \ - 'weekNum': rjust(`weekNum`, 2), \ - 'weekNumMonth': weekNumMonth, \ - 'weekNumMonth2': weekNumMonth2, \ - 'dayNum': rjust(`dayNum`, 3) } - - print " { { %(day)s, "\ - "wxDateTime::%(month)s, "\ - "%(year)d }, "\ - "%(weekNum)s, "\ - "%(weekNumMonth)s, "\ - "%(weekNumMonth2)s, "\ - "%(dayNum)s }," % data - - */ - static const WeekNumberTestData weekNumberTestDates[] = - { - { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 }, - { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 }, - { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 }, - { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 }, - { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 }, - { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 }, - { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 }, - { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 }, - { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 }, - { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 }, - { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 }, - { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 }, - { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 }, - { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 }, - { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 }, - { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 }, - { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 }, - { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 }, - { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 }, - { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 }, - { { 30, wxDateTime::Dec, 2003 }, 1, 5, 5, 364 }, - { { 2, wxDateTime::Jan, 2004 }, 1, 1, 1, 2 }, - }; - - for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ ) - { - const WeekNumberTestData& wn = weekNumberTestDates[n]; - const Date& d = wn.date; - - wxDateTime dt = d.DT(); - - wxDateTime::wxDateTime_t - week = dt.GetWeekOfYear(wxDateTime::Monday_First), - wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First), - wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First), - dnum = dt.GetDayOfYear(); - - CPPUNIT_ASSERT( dnum == wn.dnum ); - CPPUNIT_ASSERT( wmon == wn.wmon ); - CPPUNIT_ASSERT( wmon2 == wn.wmon2 ); - CPPUNIT_ASSERT( week == wn.week ); - - int year = d.year; - if ( week == 1 && d.month != wxDateTime::Jan ) - { - // this means we're in the first week of the next year - year++; - } - - wxDateTime - dt2 = wxDateTime::SetToWeekOfYear(year, week, dt.GetWeekDay()); - CPPUNIT_ASSERT( dt2 == dt ); - } -} - -// test DST applicability -void DateTimeTestCase::TestTimeDST() -{ - // taken from http://www.energy.ca.gov/daylightsaving.html - static const Date datesDST[2][2004 - 1900 + 1] = - { - { - { 1, wxDateTime::Apr, 1990 }, - { 7, wxDateTime::Apr, 1991 }, - { 5, wxDateTime::Apr, 1992 }, - { 4, wxDateTime::Apr, 1993 }, - { 3, wxDateTime::Apr, 1994 }, - { 2, wxDateTime::Apr, 1995 }, - { 7, wxDateTime::Apr, 1996 }, - { 6, wxDateTime::Apr, 1997 }, - { 5, wxDateTime::Apr, 1998 }, - { 4, wxDateTime::Apr, 1999 }, - { 2, wxDateTime::Apr, 2000 }, - { 1, wxDateTime::Apr, 2001 }, - { 7, wxDateTime::Apr, 2002 }, - { 6, wxDateTime::Apr, 2003 }, - { 4, wxDateTime::Apr, 2004 }, - }, - { - { 28, wxDateTime::Oct, 1990 }, - { 27, wxDateTime::Oct, 1991 }, - { 25, wxDateTime::Oct, 1992 }, - { 31, wxDateTime::Oct, 1993 }, - { 30, wxDateTime::Oct, 1994 }, - { 29, wxDateTime::Oct, 1995 }, - { 27, wxDateTime::Oct, 1996 }, - { 26, wxDateTime::Oct, 1997 }, - { 25, wxDateTime::Oct, 1998 }, - { 31, wxDateTime::Oct, 1999 }, - { 29, wxDateTime::Oct, 2000 }, - { 28, wxDateTime::Oct, 2001 }, - { 27, wxDateTime::Oct, 2002 }, - { 26, wxDateTime::Oct, 2003 }, - { 31, wxDateTime::Oct, 2004 }, - } - }; - - for ( int year = 1990; year < 2005; year++ ) - { - wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA), - dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA); - - size_t n = year - 1990; - const Date& dBegin = datesDST[0][n]; - const Date& dEnd = datesDST[1][n]; - - CPPUNIT_ASSERT( dBegin.SameDay(dtBegin.GetTm()) ); - CPPUNIT_ASSERT( dEnd.SameDay(dtEnd.GetTm()) ); - } -} - -// 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 - CompareDate, // dates only - CompareTime // time only - }; - - static const struct - { - CompareKind compareKind; - const wxChar *format; - } formatTestFormats[] = - { - { CompareBoth, _T("---> %c") }, - { CompareDate, _T("Date is %A, %d of %B, in year %Y") }, - { CompareBoth, _T("Date is %x, time is %X") }, - { CompareTime, _T("Time is %H:%M:%S or %I:%M:%S %p") }, - { CompareNone, _T("The day of year: %j, the week of year: %W") }, - { CompareDate, _T("ISO date without separators: %Y%m%d") }, - }; - - static const Date formatTestDates[] = - { - { 29, wxDateTime::May, 1976, 18, 30, 00 }, - { 31, wxDateTime::Dec, 1999, 23, 30, 00 }, -#if 0 - // this test can't work for other centuries because it uses two digit - // years in formats, so don't even try it - { 29, wxDateTime::May, 2076, 18, 30, 00 }, - { 29, wxDateTime::Feb, 2400, 02, 15, 25 }, - { 01, wxDateTime::Jan, -52, 03, 16, 47 }, -#endif - }; - - for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ ) - { - wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT(); - for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ ) - { - wxString s = dt.Format(formatTestFormats[n].format); - - // what can we recover? - int kind = formatTestFormats[n].compareKind; - - // convert back - wxDateTime dt2; - const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format); - if ( !result ) - { - // converion failed - should it have? - CPPUNIT_ASSERT( kind == CompareNone ); - } - else // conversion succeeded - { - // should have parsed the entire string - CPPUNIT_ASSERT( !*result ); - - switch ( kind ) - { - case CompareBoth: - CPPUNIT_ASSERT( dt2 == dt ); - break; - - case CompareDate: - CPPUNIT_ASSERT( dt.IsSameDate(dt2) ); - break; - - case CompareTime: - CPPUNIT_ASSERT( dt.IsSameTime(dt2) ); - break; - } - } - } - } -} - -void DateTimeTestCase::TestTimeTicks() -{ - for ( size_t n = 0; n < WXSIZEOF(testDates); n++ ) - { - const Date& d = testDates[n]; - if ( d.ticks == -1 ) - continue; - - wxDateTime dt = d.DT(); - long ticks = (dt.GetValue() / 1000).ToLong(); - CPPUNIT_ASSERT( ticks == d.ticks ); - - dt = d.DT().ToTimezone(wxDateTime::GMT0); - ticks = (dt.GetValue() / 1000).ToLong(); - CPPUNIT_ASSERT( ticks == d.gmticks ); - } -} - -// test text -> wxDateTime conversion -void DateTimeTestCase::TestTimeParse() -{ - static const struct ParseTestData - { - const wxChar *format; - Date date; - bool good; - } parseTestDates[] = - { - { _T("Sat, 18 Dec 1999 00:46:40 +0100"), { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, true }, - { _T("Wed, 1 Dec 1999 05:17:20 +0300"), { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, true }, - }; - - for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ ) - { - const wxChar *format = parseTestDates[n].format; - - wxDateTime dt; - if ( dt.ParseRfc822Date(format) ) - { - CPPUNIT_ASSERT( parseTestDates[n].good ); - - wxDateTime dtReal = parseTestDates[n].date.DT(); - CPPUNIT_ASSERT( dt == dtReal ); - } - else // failed to parse - { - CPPUNIT_ASSERT( !parseTestDates[n].good ); - } - } -} - -void DateTimeTestCase::TestTimeArithmetics() -{ - static const wxDateSpan testArithmData[] = - { - wxDateSpan::Day(), - wxDateSpan::Week(), - wxDateSpan::Month(), - wxDateSpan::Year(), - }; - - // the test will *not* work with arbitrary date! - wxDateTime dt(2, wxDateTime::Dec, 1999), - dt1, - dt2; - - for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ ) - { - const wxDateSpan& span = testArithmData[n]; - dt1 = dt + span; - dt2 = dt - span; - - CPPUNIT_ASSERT( dt1 - span == dt ); - CPPUNIT_ASSERT( dt2 + span == dt ); - CPPUNIT_ASSERT( dt2 + 2*span == dt1 ); - } -} - diff --git a/tests/datetime/datetimetest.cpp b/tests/datetime/datetimetest.cpp new file mode 100644 index 0000000000..bc68b2f7cc --- /dev/null +++ b/tests/datetime/datetimetest.cpp @@ -0,0 +1,679 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/datetime/datetime.cpp +// Purpose: wxDateTime unit test +// Author: Vadim Zeitlin +// Created: 2004-06-23 (extracted from samples/console/console.cpp) +// RCS-ID: $Id$ +// Copyright: (c) 2004 Vadim Zeitlin +/////////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#endif // WX_PRECOMP + +#include "wx/datetime.h" + +#include "wx/cppunit.h" + +// ---------------------------------------------------------------------------- +// broken down date representation used for testing +// ---------------------------------------------------------------------------- + +struct Date +{ + wxDateTime::wxDateTime_t day; + wxDateTime::Month month; + int year; + wxDateTime::wxDateTime_t hour, min, sec; + double jdn; + wxDateTime::WeekDay wday; + time_t gmticks, ticks; + + void Init(const wxDateTime::Tm& tm) + { + day = tm.mday; + month = tm.mon; + year = tm.year; + hour = tm.hour; + min = tm.min; + sec = tm.sec; + jdn = 0.0; + gmticks = ticks = -1; + } + + wxDateTime DT() const + { return wxDateTime(day, month, year, hour, min, sec); } + + bool SameDay(const wxDateTime::Tm& tm) const + { + return day == tm.mday && month == tm.mon && year == tm.year; + } + + wxString Format() const + { + wxString s; + s.Printf(_T("%02d:%02d:%02d %10s %02d, %4d%s"), + hour, min, sec, + wxDateTime::GetMonthName(month).c_str(), + day, + abs(wxDateTime::ConvertYearToBC(year)), + year > 0 ? _T("AD") : _T("BC")); + return s; + } + + wxString FormatDate() const + { + wxString s; + s.Printf(_T("%02d-%s-%4d%s"), + day, + wxDateTime::GetMonthName(month, wxDateTime::Name_Abbr).c_str(), + abs(wxDateTime::ConvertYearToBC(year)), + year > 0 ? _T("AD") : _T("BC")); + return s; + } +}; + +// ---------------------------------------------------------------------------- +// test data +// ---------------------------------------------------------------------------- + +static const Date testDates[] = +{ + { 1, wxDateTime::Jan, 1970, 00, 00, 00, 2440587.5, wxDateTime::Thu, 0, -3600 }, + { 7, wxDateTime::Feb, 2036, 00, 00, 00, 2464730.5, wxDateTime::Thu, -1, -1 }, + { 8, wxDateTime::Feb, 2036, 00, 00, 00, 2464731.5, wxDateTime::Fri, -1, -1 }, + { 1, wxDateTime::Jan, 2037, 00, 00, 00, 2465059.5, wxDateTime::Thu, -1, -1 }, + { 1, wxDateTime::Jan, 2038, 00, 00, 00, 2465424.5, wxDateTime::Fri, -1, -1 }, + { 21, wxDateTime::Jan, 2222, 00, 00, 00, 2532648.5, wxDateTime::Mon, -1, -1 }, + { 29, wxDateTime::May, 1976, 12, 00, 00, 2442928.0, wxDateTime::Sat, 202219200, 202212000 }, + { 29, wxDateTime::Feb, 1976, 00, 00, 00, 2442837.5, wxDateTime::Sun, 194400000, 194396400 }, + { 1, wxDateTime::Jan, 1900, 12, 00, 00, 2415021.0, wxDateTime::Mon, -1, -1 }, + { 1, wxDateTime::Jan, 1900, 00, 00, 00, 2415020.5, wxDateTime::Mon, -1, -1 }, + { 15, wxDateTime::Oct, 1582, 00, 00, 00, 2299160.5, wxDateTime::Fri, -1, -1 }, + { 4, wxDateTime::Oct, 1582, 00, 00, 00, 2299149.5, wxDateTime::Mon, -1, -1 }, + { 1, wxDateTime::Mar, 1, 00, 00, 00, 1721484.5, wxDateTime::Thu, -1, -1 }, + { 1, wxDateTime::Jan, 1, 00, 00, 00, 1721425.5, wxDateTime::Mon, -1, -1 }, + { 31, wxDateTime::Dec, 0, 00, 00, 00, 1721424.5, wxDateTime::Sun, -1, -1 }, + { 1, wxDateTime::Jan, 0, 00, 00, 00, 1721059.5, wxDateTime::Sat, -1, -1 }, + { 12, wxDateTime::Aug, -1234, 00, 00, 00, 1270573.5, wxDateTime::Fri, -1, -1 }, + { 12, wxDateTime::Aug, -4000, 00, 00, 00, 260313.5, wxDateTime::Sat, -1, -1 }, + { 24, wxDateTime::Nov, -4713, 00, 00, 00, -0.5, wxDateTime::Mon, -1, -1 }, +}; + + +// ---------------------------------------------------------------------------- +// test class +// ---------------------------------------------------------------------------- + +class DateTimeTestCase : public CppUnit::TestCase +{ +public: + DateTimeTestCase() { } + +private: + CPPUNIT_TEST_SUITE( DateTimeTestCase ); + CPPUNIT_TEST( TestLeapYears ); + CPPUNIT_TEST( TestTimeSet ); + CPPUNIT_TEST( TestTimeJDN ); + CPPUNIT_TEST( TestTimeWNumber ); + CPPUNIT_TEST( TestTimeWDays ); + CPPUNIT_TEST( TestTimeDST ); + CPPUNIT_TEST( TestTimeFormat ); + CPPUNIT_TEST( TestTimeTicks ); + CPPUNIT_TEST( TestTimeParse ); + CPPUNIT_TEST( TestTimeArithmetics ); + CPPUNIT_TEST_SUITE_END(); + + void TestLeapYears(); + void TestTimeSet(); + void TestTimeJDN(); + void TestTimeWNumber(); + void TestTimeWDays(); + void TestTimeDST(); + void TestTimeFormat(); + void TestTimeTicks(); + void TestTimeParse(); + void TestTimeArithmetics(); + + DECLARE_NO_COPY_CLASS(DateTimeTestCase) +}; + +// register in the unnamed registry so that these tests are run by default +CPPUNIT_TEST_SUITE_REGISTRATION( DateTimeTestCase ); + +// also include in it's own registry so that these tests can be run alone +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( DateTimeTestCase, "DateTimeTestCase" ); + +// ============================================================================ +// implementation +// ============================================================================ + +// test leap years detection +void DateTimeTestCase::TestLeapYears() +{ + static const struct LeapYearTestData + { + int year; + bool isLeap; + } years[] = + { + { 1900, false }, + { 1990, false }, + { 1976, true }, + { 2000, true }, + { 2030, false }, + { 1984, true }, + { 2100, false }, + { 2400, true }, + }; + + for ( size_t n = 0; n < WXSIZEOF(years); n++ ) + { + const LeapYearTestData& y = years[n]; + + CPPUNIT_ASSERT( wxDateTime::IsLeapYear(y.year) == y.isLeap ); + } +} + +// test constructing wxDateTime objects +void DateTimeTestCase::TestTimeSet() +{ + for ( size_t n = 0; n < WXSIZEOF(testDates); n++ ) + { + const Date& d1 = testDates[n]; + wxDateTime dt = d1.DT(); + + Date d2; + d2.Init(dt.GetTm()); + + wxString s1 = d1.Format(), + s2 = d2.Format(); + + CPPUNIT_ASSERT( s1 == s2 ); + } +} + +// test conversions to JDN &c +void DateTimeTestCase::TestTimeJDN() +{ + for ( size_t n = 0; n < WXSIZEOF(testDates); n++ ) + { + const Date& d = testDates[n]; + wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec); + double jdn = dt.GetJulianDayNumber(); + + CPPUNIT_ASSERT( jdn == d.jdn ); + + dt.Set(jdn); + CPPUNIT_ASSERT( dt.GetJulianDayNumber() == jdn ); + } +} + +// test week days computation +void DateTimeTestCase::TestTimeWDays() +{ + // test GetWeekDay() + size_t n; + for ( n = 0; n < WXSIZEOF(testDates); n++ ) + { + const Date& d = testDates[n]; + wxDateTime dt(d.day, d.month, d.year, d.hour, d.min, d.sec); + + wxDateTime::WeekDay wday = dt.GetWeekDay(); + CPPUNIT_ASSERT( wday == d.wday ); + } + + // test SetToWeekDay() + struct WeekDateTestData + { + Date date; // the real date (precomputed) + int nWeek; // its week index in the month + wxDateTime::WeekDay wday; // the weekday + wxDateTime::Month month; // the month + int year; // and the year + + wxString Format() const + { + wxString s, which; + switch ( nWeek < -1 ? -nWeek : nWeek ) + { + case 1: which = _T("first"); break; + case 2: which = _T("second"); break; + case 3: which = _T("third"); break; + case 4: which = _T("fourth"); break; + case 5: which = _T("fifth"); break; + + case -1: which = _T("last"); break; + } + + if ( nWeek < -1 ) + { + which += _T(" from end"); + } + + s.Printf(_T("The %s %s of %s in %d"), + which.c_str(), + wxDateTime::GetWeekDayName(wday).c_str(), + wxDateTime::GetMonthName(month).c_str(), + year); + + return s; + } + }; + + // the array data was generated by the following python program + /* +from DateTime import * +from whrandom import * +from string import * + +monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] +wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ] + +week = DateTimeDelta(7) + +for n in range(20): + year = randint(1900, 2100) + month = randint(1, 12) + day = randint(1, 28) + dt = DateTime(year, month, day) + wday = dt.day_of_week + + countFromEnd = choice([-1, 1]) + weekNum = 0; + + while dt.month is month: + dt = dt - countFromEnd * week + weekNum = weekNum + countFromEnd + + data = { 'day': rjust(`day`, 2), 'month': monthNames[month - 1], 'year': year, 'weekNum': rjust(`weekNum`, 2), 'wday': wdayNames[wday] } + + print "{ { %(day)s, wxDateTime::%(month)s, %(year)d }, %(weekNum)d, "\ + "wxDateTime::%(wday)s, wxDateTime::%(month)s, %(year)d }," % data + */ + + static const WeekDateTestData weekDatesTestData[] = + { + { { 20, wxDateTime::Mar, 2045 }, 3, wxDateTime::Mon, wxDateTime::Mar, 2045 }, + { { 5, wxDateTime::Jun, 1985 }, -4, wxDateTime::Wed, wxDateTime::Jun, 1985 }, + { { 12, wxDateTime::Nov, 1961 }, -3, wxDateTime::Sun, wxDateTime::Nov, 1961 }, + { { 27, wxDateTime::Feb, 2093 }, -1, wxDateTime::Fri, wxDateTime::Feb, 2093 }, + { { 4, wxDateTime::Jul, 2070 }, -4, wxDateTime::Fri, wxDateTime::Jul, 2070 }, + { { 2, wxDateTime::Apr, 1906 }, -5, wxDateTime::Mon, wxDateTime::Apr, 1906 }, + { { 19, wxDateTime::Jul, 2023 }, -2, wxDateTime::Wed, wxDateTime::Jul, 2023 }, + { { 5, wxDateTime::May, 1958 }, -4, wxDateTime::Mon, wxDateTime::May, 1958 }, + { { 11, wxDateTime::Aug, 1900 }, 2, wxDateTime::Sat, wxDateTime::Aug, 1900 }, + { { 14, wxDateTime::Feb, 1945 }, 2, wxDateTime::Wed, wxDateTime::Feb, 1945 }, + { { 25, wxDateTime::Jul, 1967 }, -1, wxDateTime::Tue, wxDateTime::Jul, 1967 }, + { { 9, wxDateTime::May, 1916 }, -4, wxDateTime::Tue, wxDateTime::May, 1916 }, + { { 20, wxDateTime::Jun, 1927 }, 3, wxDateTime::Mon, wxDateTime::Jun, 1927 }, + { { 2, wxDateTime::Aug, 2000 }, 1, wxDateTime::Wed, wxDateTime::Aug, 2000 }, + { { 20, wxDateTime::Apr, 2044 }, 3, wxDateTime::Wed, wxDateTime::Apr, 2044 }, + { { 20, wxDateTime::Feb, 1932 }, -2, wxDateTime::Sat, wxDateTime::Feb, 1932 }, + { { 25, wxDateTime::Jul, 2069 }, 4, wxDateTime::Thu, wxDateTime::Jul, 2069 }, + { { 3, wxDateTime::Apr, 1925 }, 1, wxDateTime::Fri, wxDateTime::Apr, 1925 }, + { { 21, wxDateTime::Mar, 2093 }, 3, wxDateTime::Sat, wxDateTime::Mar, 2093 }, + { { 3, wxDateTime::Dec, 2074 }, -5, wxDateTime::Mon, wxDateTime::Dec, 2074 }, + + }; + + wxDateTime dt; + for ( n = 0; n < WXSIZEOF(weekDatesTestData); n++ ) + { + const WeekDateTestData& wd = weekDatesTestData[n]; + + dt.SetToWeekDay(wd.wday, wd.nWeek, wd.month, wd.year); + + const Date& d = wd.date; + CPPUNIT_ASSERT( d.SameDay(dt.GetTm()) ); + } +} + +// test the computation of (ISO) week numbers +void DateTimeTestCase::TestTimeWNumber() +{ + struct WeekNumberTestData + { + Date date; // the date + wxDateTime::wxDateTime_t week; // the week number in the year + wxDateTime::wxDateTime_t wmon; // the week number in the month + wxDateTime::wxDateTime_t wmon2; // same but week starts with Sun + wxDateTime::wxDateTime_t dnum; // day number in the year + }; + + // data generated with the following python script: + /* +from DateTime import * +from whrandom import * +from string import * + +monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] +wdayNames = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ] + +def GetMonthWeek(dt): + weekNumMonth = dt.iso_week[1] - DateTime(dt.year, dt.month, 1).iso_week[1] + 1 + if weekNumMonth < 0: + weekNumMonth = weekNumMonth + 53 + return weekNumMonth + +def GetLastSundayBefore(dt): + if dt.iso_week[2] == 7: + return dt + else: + return dt - DateTimeDelta(dt.iso_week[2]) + +for n in range(20): + year = randint(1900, 2100) + month = randint(1, 12) + day = randint(1, 28) + dt = DateTime(year, month, day) + dayNum = dt.day_of_year + weekNum = dt.iso_week[1] + weekNumMonth = GetMonthWeek(dt) + + weekNumMonth2 = 0 + dtSunday = GetLastSundayBefore(dt) + + while dtSunday >= GetLastSundayBefore(DateTime(dt.year, dt.month, 1)): + weekNumMonth2 = weekNumMonth2 + 1 + dtSunday = dtSunday - DateTimeDelta(7) + + data = { 'day': rjust(`day`, 2), \ + 'month': monthNames[month - 1], \ + 'year': year, \ + 'weekNum': rjust(`weekNum`, 2), \ + 'weekNumMonth': weekNumMonth, \ + 'weekNumMonth2': weekNumMonth2, \ + 'dayNum': rjust(`dayNum`, 3) } + + print " { { %(day)s, "\ + "wxDateTime::%(month)s, "\ + "%(year)d }, "\ + "%(weekNum)s, "\ + "%(weekNumMonth)s, "\ + "%(weekNumMonth2)s, "\ + "%(dayNum)s }," % data + + */ + static const WeekNumberTestData weekNumberTestDates[] = + { + { { 27, wxDateTime::Dec, 1966 }, 52, 5, 5, 361 }, + { { 22, wxDateTime::Jul, 1926 }, 29, 4, 4, 203 }, + { { 22, wxDateTime::Oct, 2076 }, 43, 4, 4, 296 }, + { { 1, wxDateTime::Jul, 1967 }, 26, 1, 1, 182 }, + { { 8, wxDateTime::Nov, 2004 }, 46, 2, 2, 313 }, + { { 21, wxDateTime::Mar, 1920 }, 12, 3, 4, 81 }, + { { 7, wxDateTime::Jan, 1965 }, 1, 2, 2, 7 }, + { { 19, wxDateTime::Oct, 1999 }, 42, 4, 4, 292 }, + { { 13, wxDateTime::Aug, 1955 }, 32, 2, 2, 225 }, + { { 18, wxDateTime::Jul, 2087 }, 29, 3, 3, 199 }, + { { 2, wxDateTime::Sep, 2028 }, 35, 1, 1, 246 }, + { { 28, wxDateTime::Jul, 1945 }, 30, 5, 4, 209 }, + { { 15, wxDateTime::Jun, 1901 }, 24, 3, 3, 166 }, + { { 10, wxDateTime::Oct, 1939 }, 41, 3, 2, 283 }, + { { 3, wxDateTime::Dec, 1965 }, 48, 1, 1, 337 }, + { { 23, wxDateTime::Feb, 1940 }, 8, 4, 4, 54 }, + { { 2, wxDateTime::Jan, 1987 }, 1, 1, 1, 2 }, + { { 11, wxDateTime::Aug, 2079 }, 32, 2, 2, 223 }, + { { 2, wxDateTime::Feb, 2063 }, 5, 1, 1, 33 }, + { { 16, wxDateTime::Oct, 1942 }, 42, 3, 3, 289 }, + { { 30, wxDateTime::Dec, 2003 }, 1, 5, 5, 364 }, + { { 2, wxDateTime::Jan, 2004 }, 1, 1, 1, 2 }, + }; + + for ( size_t n = 0; n < WXSIZEOF(weekNumberTestDates); n++ ) + { + const WeekNumberTestData& wn = weekNumberTestDates[n]; + const Date& d = wn.date; + + wxDateTime dt = d.DT(); + + wxDateTime::wxDateTime_t + week = dt.GetWeekOfYear(wxDateTime::Monday_First), + wmon = dt.GetWeekOfMonth(wxDateTime::Monday_First), + wmon2 = dt.GetWeekOfMonth(wxDateTime::Sunday_First), + dnum = dt.GetDayOfYear(); + + CPPUNIT_ASSERT( dnum == wn.dnum ); + CPPUNIT_ASSERT( wmon == wn.wmon ); + CPPUNIT_ASSERT( wmon2 == wn.wmon2 ); + CPPUNIT_ASSERT( week == wn.week ); + + int year = d.year; + if ( week == 1 && d.month != wxDateTime::Jan ) + { + // this means we're in the first week of the next year + year++; + } + + wxDateTime + dt2 = wxDateTime::SetToWeekOfYear(year, week, dt.GetWeekDay()); + CPPUNIT_ASSERT( dt2 == dt ); + } +} + +// test DST applicability +void DateTimeTestCase::TestTimeDST() +{ + // taken from http://www.energy.ca.gov/daylightsaving.html + static const Date datesDST[2][2004 - 1900 + 1] = + { + { + { 1, wxDateTime::Apr, 1990 }, + { 7, wxDateTime::Apr, 1991 }, + { 5, wxDateTime::Apr, 1992 }, + { 4, wxDateTime::Apr, 1993 }, + { 3, wxDateTime::Apr, 1994 }, + { 2, wxDateTime::Apr, 1995 }, + { 7, wxDateTime::Apr, 1996 }, + { 6, wxDateTime::Apr, 1997 }, + { 5, wxDateTime::Apr, 1998 }, + { 4, wxDateTime::Apr, 1999 }, + { 2, wxDateTime::Apr, 2000 }, + { 1, wxDateTime::Apr, 2001 }, + { 7, wxDateTime::Apr, 2002 }, + { 6, wxDateTime::Apr, 2003 }, + { 4, wxDateTime::Apr, 2004 }, + }, + { + { 28, wxDateTime::Oct, 1990 }, + { 27, wxDateTime::Oct, 1991 }, + { 25, wxDateTime::Oct, 1992 }, + { 31, wxDateTime::Oct, 1993 }, + { 30, wxDateTime::Oct, 1994 }, + { 29, wxDateTime::Oct, 1995 }, + { 27, wxDateTime::Oct, 1996 }, + { 26, wxDateTime::Oct, 1997 }, + { 25, wxDateTime::Oct, 1998 }, + { 31, wxDateTime::Oct, 1999 }, + { 29, wxDateTime::Oct, 2000 }, + { 28, wxDateTime::Oct, 2001 }, + { 27, wxDateTime::Oct, 2002 }, + { 26, wxDateTime::Oct, 2003 }, + { 31, wxDateTime::Oct, 2004 }, + } + }; + + for ( int year = 1990; year < 2005; year++ ) + { + wxDateTime dtBegin = wxDateTime::GetBeginDST(year, wxDateTime::USA), + dtEnd = wxDateTime::GetEndDST(year, wxDateTime::USA); + + size_t n = year - 1990; + const Date& dBegin = datesDST[0][n]; + const Date& dEnd = datesDST[1][n]; + + CPPUNIT_ASSERT( dBegin.SameDay(dtBegin.GetTm()) ); + CPPUNIT_ASSERT( dEnd.SameDay(dtEnd.GetTm()) ); + } +} + +// 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 + CompareDate, // dates only + CompareTime // time only + }; + + static const struct + { + CompareKind compareKind; + const wxChar *format; + } formatTestFormats[] = + { + { CompareBoth, _T("---> %c") }, + { CompareDate, _T("Date is %A, %d of %B, in year %Y") }, + { CompareBoth, _T("Date is %x, time is %X") }, + { CompareTime, _T("Time is %H:%M:%S or %I:%M:%S %p") }, + { CompareNone, _T("The day of year: %j, the week of year: %W") }, + { CompareDate, _T("ISO date without separators: %Y%m%d") }, + }; + + static const Date formatTestDates[] = + { + { 29, wxDateTime::May, 1976, 18, 30, 00 }, + { 31, wxDateTime::Dec, 1999, 23, 30, 00 }, +#if 0 + // this test can't work for other centuries because it uses two digit + // years in formats, so don't even try it + { 29, wxDateTime::May, 2076, 18, 30, 00 }, + { 29, wxDateTime::Feb, 2400, 02, 15, 25 }, + { 01, wxDateTime::Jan, -52, 03, 16, 47 }, +#endif + }; + + for ( size_t d = 0; d < WXSIZEOF(formatTestDates) + 1; d++ ) + { + wxDateTime dt = d == 0 ? wxDateTime::Now() : formatTestDates[d - 1].DT(); + for ( size_t n = 0; n < WXSIZEOF(formatTestFormats); n++ ) + { + wxString s = dt.Format(formatTestFormats[n].format); + + // what can we recover? + int kind = formatTestFormats[n].compareKind; + + // convert back + wxDateTime dt2; + const wxChar *result = dt2.ParseFormat(s, formatTestFormats[n].format); + if ( !result ) + { + // converion failed - should it have? + CPPUNIT_ASSERT( kind == CompareNone ); + } + else // conversion succeeded + { + // should have parsed the entire string + CPPUNIT_ASSERT( !*result ); + + switch ( kind ) + { + case CompareBoth: + CPPUNIT_ASSERT( dt2 == dt ); + break; + + case CompareDate: + CPPUNIT_ASSERT( dt.IsSameDate(dt2) ); + break; + + case CompareTime: + CPPUNIT_ASSERT( dt.IsSameTime(dt2) ); + break; + } + } + } + } +} + +void DateTimeTestCase::TestTimeTicks() +{ + for ( size_t n = 0; n < WXSIZEOF(testDates); n++ ) + { + const Date& d = testDates[n]; + if ( d.ticks == -1 ) + continue; + + wxDateTime dt = d.DT(); + long ticks = (dt.GetValue() / 1000).ToLong(); + CPPUNIT_ASSERT( ticks == d.ticks ); + + dt = d.DT().ToTimezone(wxDateTime::GMT0); + ticks = (dt.GetValue() / 1000).ToLong(); + CPPUNIT_ASSERT( ticks == d.gmticks ); + } +} + +// test text -> wxDateTime conversion +void DateTimeTestCase::TestTimeParse() +{ + static const struct ParseTestData + { + const wxChar *format; + Date date; + bool good; + } parseTestDates[] = + { + { _T("Sat, 18 Dec 1999 00:46:40 +0100"), { 18, wxDateTime::Dec, 1999, 00, 46, 40 }, true }, + { _T("Wed, 1 Dec 1999 05:17:20 +0300"), { 1, wxDateTime::Dec, 1999, 03, 17, 20 }, true }, + }; + + for ( size_t n = 0; n < WXSIZEOF(parseTestDates); n++ ) + { + const wxChar *format = parseTestDates[n].format; + + wxDateTime dt; + if ( dt.ParseRfc822Date(format) ) + { + CPPUNIT_ASSERT( parseTestDates[n].good ); + + wxDateTime dtReal = parseTestDates[n].date.DT(); + CPPUNIT_ASSERT( dt == dtReal ); + } + else // failed to parse + { + CPPUNIT_ASSERT( !parseTestDates[n].good ); + } + } +} + +void DateTimeTestCase::TestTimeArithmetics() +{ + static const wxDateSpan testArithmData[] = + { + wxDateSpan::Day(), + wxDateSpan::Week(), + wxDateSpan::Month(), + wxDateSpan::Year(), + }; + + // the test will *not* work with arbitrary date! + wxDateTime dt(2, wxDateTime::Dec, 1999), + dt1, + dt2; + + for ( size_t n = 0; n < WXSIZEOF(testArithmData); n++ ) + { + const wxDateSpan& span = testArithmData[n]; + dt1 = dt + span; + dt2 = dt - span; + + CPPUNIT_ASSERT( dt1 - span == dt ); + CPPUNIT_ASSERT( dt2 + span == dt ); + CPPUNIT_ASSERT( dt2 + 2*span == dt1 ); + } +} + diff --git a/tests/fileconf/fileconf.cpp b/tests/fileconf/fileconf.cpp deleted file mode 100644 index 7b8216b75e..0000000000 --- a/tests/fileconf/fileconf.cpp +++ /dev/null @@ -1,356 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Name: tests/fileconf/fileconf.cpp -// Purpose: wxFileConf unit test -// Author: Vadim Zeitlin -// Created: 2004-09-19 -// RCS-ID: $Id$ -// Copyright: (c) 2004 Vadim Zeitlin -/////////////////////////////////////////////////////////////////////////////// - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#if wxUSE_FILECONFIG - -#ifndef WX_PRECOMP -#endif // WX_PRECOMP - -#include "wx/fileconf.h" -#include "wx/sstream.h" - -#include "wx/cppunit.h" - -static const wxChar *testconfig = -_T("[root]\n") -_T("entry=value\n") -_T("[root/group1]\n") -_T("[root/group1/subgroup]\n") -_T("subentry=subvalue\n") -_T("subentry2=subvalue2\n") -_T("[root/group2]\n") -; - -// ---------------------------------------------------------------------------- -// 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( Save ); - CPPUNIT_TEST( DeleteEntry ); - CPPUNIT_TEST( DeleteGroup ); - CPPUNIT_TEST( DeleteAll ); - CPPUNIT_TEST( RenameEntry ); - CPPUNIT_TEST( RenameGroup ); - CPPUNIT_TEST_SUITE_END(); - - void Path(); - void AddEntries(); - void GetEntries(); - void GetGroups(); - void HasEntry(); - void HasGroup(); - void Save(); - void DeleteEntry(); - void DeleteGroup(); - void DeleteAll(); - void RenameEntry(); - void RenameGroup(); - - static wxString ChangePath(wxFileConfig& fc, const wxChar *path) - { - fc.SetPath(path); - - return fc.GetPath(); - } - - static wxString Dump(wxFileConfig& fc) - { - wxStringOutputStream sos; - fc.Save(sos); - return wxTextFile::Translate(sos.GetString(), wxTextFileType_Unix); - } - - void CheckGroupEntries(const wxFileConfig& fc, - const wxChar *path, - size_t nEntries, - ...); - void CheckGroupSubgroups(const wxFileConfig& fc, - const wxChar *path, - size_t nGroups, - ...); - - DECLARE_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 it's own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileConfigTestCase, "FileConfigTestCase" ); - -void FileConfigTestCase::Path() -{ - wxStringInputStream sis(testconfig); - wxFileConfig fc(sis); - - CPPUNIT_ASSERT( ChangePath(fc, _T("")) == _T("") ); - CPPUNIT_ASSERT( ChangePath(fc, _T("/")) == _T("") ); - CPPUNIT_ASSERT( ChangePath(fc, _T("root")) == _T("/root") ); - CPPUNIT_ASSERT( ChangePath(fc, _T("/root")) == _T("/root") ); - CPPUNIT_ASSERT( ChangePath(fc, _T("/root/group1/subgroup")) == _T("/root/group1/subgroup") ); - CPPUNIT_ASSERT( ChangePath(fc, _T("/root/group2")) == _T("/root/group2") ); -} - -void FileConfigTestCase::AddEntries() -{ - wxFileConfig fc; - - CPPUNIT_ASSERT( Dump(fc) == _T("") ); - - fc.Write(_T("/Foo"), _T("foo")); - CPPUNIT_ASSERT( Dump(fc) == _T("Foo=foo\n") ); - - fc.Write(_T("/Bar/Baz"), _T("baz")); - CPPUNIT_ASSERT( Dump(fc) == _T("Foo=foo\n[Bar]\nBaz=baz\n") ); - - fc.DeleteAll(); - CPPUNIT_ASSERT( Dump(fc) == _T("") ); - - fc.Write(_T("/Bar/Baz"), _T("baz")); - CPPUNIT_ASSERT( Dump(fc) == _T("[Bar]\nBaz=baz\n") ); - - fc.Write(_T("/Foo"), _T("foo")); - CPPUNIT_ASSERT( Dump(fc) == _T("Foo=foo\n[Bar]\nBaz=baz\n") ); -} - -void -FileConfigTestCase::CheckGroupEntries(const wxFileConfig& fc, - const wxChar *path, - size_t nEntries, - ...) -{ - wxConfigPathChanger change(&fc, wxString(path) + _T("/")); - - CPPUNIT_ASSERT( fc.GetNumberOfEntries() == nEntries ); - - va_list ap; - va_start(ap, nEntries); - - long cookie; - wxString name; - for ( bool cont = fc.GetFirstEntry(name, cookie); - cont; - cont = fc.GetNextEntry(name, cookie), nEntries-- ) - { - CPPUNIT_ASSERT( name == va_arg(ap, wxChar *) ); - } - - CPPUNIT_ASSERT( nEntries == 0 ); - - va_end(ap); -} - -void -FileConfigTestCase::CheckGroupSubgroups(const wxFileConfig& fc, - const wxChar *path, - size_t nGroups, - ...) -{ - wxConfigPathChanger change(&fc, wxString(path) + _T("/")); - - CPPUNIT_ASSERT( fc.GetNumberOfGroups() == nGroups ); - - va_list ap; - va_start(ap, nGroups); - - long cookie; - wxString name; - for ( bool cont = fc.GetFirstGroup(name, cookie); - cont; - cont = fc.GetNextGroup(name, cookie), nGroups-- ) - { - CPPUNIT_ASSERT( name == va_arg(ap, wxChar *) ); - } - - CPPUNIT_ASSERT( nGroups == 0 ); - - va_end(ap); -} - -void FileConfigTestCase::GetEntries() -{ - wxStringInputStream sis(testconfig); - wxFileConfig fc(sis); - - CheckGroupEntries(fc, _T(""), 0); - CheckGroupEntries(fc, _T("/root"), 1, _T("entry")); - CheckGroupEntries(fc, _T("/root/group1"), 0); - CheckGroupEntries(fc, _T("/root/group1/subgroup"), - 2, _T("subentry"), _T("subentry2")); -} - -void FileConfigTestCase::GetGroups() -{ - wxStringInputStream sis(testconfig); - wxFileConfig fc(sis); - - CheckGroupSubgroups(fc, _T(""), 1, _T("root")); - CheckGroupSubgroups(fc, _T("/root"), 2, _T("group1"), _T("group2")); - CheckGroupSubgroups(fc, _T("/root/group1"), 1, _T("subgroup")); - CheckGroupSubgroups(fc, _T("/root/group2"), 0); -} - -void FileConfigTestCase::HasEntry() -{ - wxStringInputStream sis(testconfig); - wxFileConfig fc(sis); - - CPPUNIT_ASSERT( !fc.HasEntry(_T("root")) ); - CPPUNIT_ASSERT( fc.HasEntry(_T("root/entry")) ); - CPPUNIT_ASSERT( fc.HasEntry(_T("/root/entry")) ); - CPPUNIT_ASSERT( fc.HasEntry(_T("root/group1/subgroup/subentry")) ); - CPPUNIT_ASSERT( !fc.HasEntry(_T("")) ); - CPPUNIT_ASSERT( !fc.HasEntry(_T("root/group1")) ); - CPPUNIT_ASSERT( !fc.HasEntry(_T("subgroup/subentry")) ); -} - -void FileConfigTestCase::HasGroup() -{ - wxStringInputStream sis(testconfig); - wxFileConfig fc(sis); - - CPPUNIT_ASSERT( fc.HasGroup(_T("root")) ); - CPPUNIT_ASSERT( fc.HasGroup(_T("root/group1")) ); - CPPUNIT_ASSERT( fc.HasGroup(_T("root/group1/subgroup")) ); - CPPUNIT_ASSERT( fc.HasGroup(_T("root/group2")) ); - CPPUNIT_ASSERT( !fc.HasGroup(_T("foot")) ); - CPPUNIT_ASSERT( !fc.HasGroup(_T("")) ); - CPPUNIT_ASSERT( !fc.HasGroup(_T("root/group")) ); - CPPUNIT_ASSERT( !fc.HasGroup(_T("root//subgroup")) ); -} - -void FileConfigTestCase::Save() -{ - wxStringInputStream sis(testconfig); - wxFileConfig fc(sis); - CPPUNIT_ASSERT( Dump(fc) == testconfig ); -} - -void FileConfigTestCase::DeleteEntry() -{ - wxStringInputStream sis(testconfig); - wxFileConfig fc(sis); - - CPPUNIT_ASSERT( !fc.DeleteEntry(_T("foo")) ); - - CPPUNIT_ASSERT( fc.DeleteEntry(_T("root/group1/subgroup/subentry")) ); - CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n") - _T("entry=value\n") - _T("[root/group1]\n") - _T("[root/group1/subgroup]\n") - _T("subentry2=subvalue2\n") - _T("[root/group2]\n") ); - - // group should be deleted now as well as it became empty - wxConfigPathChanger change(&fc, _T("root/group1/subgroup/subentry2")); - CPPUNIT_ASSERT( fc.DeleteEntry(_T("subentry2")) ); - CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n") - _T("entry=value\n") - _T("[root/group1]\n") - _T("[root/group2]\n") ); -} - -void FileConfigTestCase::DeleteGroup() -{ - wxStringInputStream sis(testconfig); - wxFileConfig fc(sis); - - CPPUNIT_ASSERT( !fc.DeleteGroup(_T("foo")) ); - - CPPUNIT_ASSERT( fc.DeleteGroup(_T("root/group1")) ); - CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n") - _T("entry=value\n") - _T("[root/group2]\n") ); - - CPPUNIT_ASSERT( fc.DeleteGroup(_T("root/group2")) ); - CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n") - _T("entry=value\n") ); - - CPPUNIT_ASSERT( fc.DeleteGroup(_T("root")) ); - CPPUNIT_ASSERT( Dump(fc).empty() ); -} - -void FileConfigTestCase::DeleteAll() -{ - wxStringInputStream sis(testconfig); - wxFileConfig fc(sis); - - CPPUNIT_ASSERT( fc.DeleteAll() ); - CPPUNIT_ASSERT( Dump(fc).empty() ); -} - -void FileConfigTestCase::RenameEntry() -{ - wxStringInputStream sis(testconfig); - wxFileConfig fc(sis); - - fc.SetPath(_T("root")); - CPPUNIT_ASSERT( fc.RenameEntry(_T("entry"), _T("newname")) ); - CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n") - _T("newname=value\n") - _T("[root/group1]\n") - _T("[root/group1/subgroup]\n") - _T("subentry=subvalue\n") - _T("subentry2=subvalue2\n") - _T("[root/group2]\n") ); - - fc.SetPath(_T("group1/subgroup")); - CPPUNIT_ASSERT( !fc.RenameEntry(_T("entry"), _T("newname")) ); - CPPUNIT_ASSERT( !fc.RenameEntry(_T("subentry"), _T("subentry2")) ); - - CPPUNIT_ASSERT( fc.RenameEntry(_T("subentry"), _T("subentry1")) ); - CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n") - _T("newname=value\n") - _T("[root/group1]\n") - _T("[root/group1/subgroup]\n") - _T("subentry2=subvalue2\n") - _T("subentry1=subvalue\n") - _T("[root/group2]\n") ); -} - -void FileConfigTestCase::RenameGroup() -{ - wxStringInputStream sis(testconfig); - wxFileConfig fc(sis); - - CPPUNIT_ASSERT( fc.RenameGroup(_T("root"), _T("foot")) ); - CPPUNIT_ASSERT( Dump(fc) == _T("[foot]\n") - _T("entry=value\n") - _T("[foot/group1]\n") - _T("[foot/group1/subgroup]\n") - _T("subentry=subvalue\n") - _T("subentry2=subvalue2\n") - _T("[foot/group2]\n") ); -} - -#endif // wxUSE_FILECONFIG - diff --git a/tests/fileconf/fileconftest.cpp b/tests/fileconf/fileconftest.cpp new file mode 100644 index 0000000000..7b8216b75e --- /dev/null +++ b/tests/fileconf/fileconftest.cpp @@ -0,0 +1,356 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/fileconf/fileconf.cpp +// Purpose: wxFileConf unit test +// Author: Vadim Zeitlin +// Created: 2004-09-19 +// RCS-ID: $Id$ +// Copyright: (c) 2004 Vadim Zeitlin +/////////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_FILECONFIG + +#ifndef WX_PRECOMP +#endif // WX_PRECOMP + +#include "wx/fileconf.h" +#include "wx/sstream.h" + +#include "wx/cppunit.h" + +static const wxChar *testconfig = +_T("[root]\n") +_T("entry=value\n") +_T("[root/group1]\n") +_T("[root/group1/subgroup]\n") +_T("subentry=subvalue\n") +_T("subentry2=subvalue2\n") +_T("[root/group2]\n") +; + +// ---------------------------------------------------------------------------- +// 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( Save ); + CPPUNIT_TEST( DeleteEntry ); + CPPUNIT_TEST( DeleteGroup ); + CPPUNIT_TEST( DeleteAll ); + CPPUNIT_TEST( RenameEntry ); + CPPUNIT_TEST( RenameGroup ); + CPPUNIT_TEST_SUITE_END(); + + void Path(); + void AddEntries(); + void GetEntries(); + void GetGroups(); + void HasEntry(); + void HasGroup(); + void Save(); + void DeleteEntry(); + void DeleteGroup(); + void DeleteAll(); + void RenameEntry(); + void RenameGroup(); + + static wxString ChangePath(wxFileConfig& fc, const wxChar *path) + { + fc.SetPath(path); + + return fc.GetPath(); + } + + static wxString Dump(wxFileConfig& fc) + { + wxStringOutputStream sos; + fc.Save(sos); + return wxTextFile::Translate(sos.GetString(), wxTextFileType_Unix); + } + + void CheckGroupEntries(const wxFileConfig& fc, + const wxChar *path, + size_t nEntries, + ...); + void CheckGroupSubgroups(const wxFileConfig& fc, + const wxChar *path, + size_t nGroups, + ...); + + DECLARE_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 it's own registry so that these tests can be run alone +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileConfigTestCase, "FileConfigTestCase" ); + +void FileConfigTestCase::Path() +{ + wxStringInputStream sis(testconfig); + wxFileConfig fc(sis); + + CPPUNIT_ASSERT( ChangePath(fc, _T("")) == _T("") ); + CPPUNIT_ASSERT( ChangePath(fc, _T("/")) == _T("") ); + CPPUNIT_ASSERT( ChangePath(fc, _T("root")) == _T("/root") ); + CPPUNIT_ASSERT( ChangePath(fc, _T("/root")) == _T("/root") ); + CPPUNIT_ASSERT( ChangePath(fc, _T("/root/group1/subgroup")) == _T("/root/group1/subgroup") ); + CPPUNIT_ASSERT( ChangePath(fc, _T("/root/group2")) == _T("/root/group2") ); +} + +void FileConfigTestCase::AddEntries() +{ + wxFileConfig fc; + + CPPUNIT_ASSERT( Dump(fc) == _T("") ); + + fc.Write(_T("/Foo"), _T("foo")); + CPPUNIT_ASSERT( Dump(fc) == _T("Foo=foo\n") ); + + fc.Write(_T("/Bar/Baz"), _T("baz")); + CPPUNIT_ASSERT( Dump(fc) == _T("Foo=foo\n[Bar]\nBaz=baz\n") ); + + fc.DeleteAll(); + CPPUNIT_ASSERT( Dump(fc) == _T("") ); + + fc.Write(_T("/Bar/Baz"), _T("baz")); + CPPUNIT_ASSERT( Dump(fc) == _T("[Bar]\nBaz=baz\n") ); + + fc.Write(_T("/Foo"), _T("foo")); + CPPUNIT_ASSERT( Dump(fc) == _T("Foo=foo\n[Bar]\nBaz=baz\n") ); +} + +void +FileConfigTestCase::CheckGroupEntries(const wxFileConfig& fc, + const wxChar *path, + size_t nEntries, + ...) +{ + wxConfigPathChanger change(&fc, wxString(path) + _T("/")); + + CPPUNIT_ASSERT( fc.GetNumberOfEntries() == nEntries ); + + va_list ap; + va_start(ap, nEntries); + + long cookie; + wxString name; + for ( bool cont = fc.GetFirstEntry(name, cookie); + cont; + cont = fc.GetNextEntry(name, cookie), nEntries-- ) + { + CPPUNIT_ASSERT( name == va_arg(ap, wxChar *) ); + } + + CPPUNIT_ASSERT( nEntries == 0 ); + + va_end(ap); +} + +void +FileConfigTestCase::CheckGroupSubgroups(const wxFileConfig& fc, + const wxChar *path, + size_t nGroups, + ...) +{ + wxConfigPathChanger change(&fc, wxString(path) + _T("/")); + + CPPUNIT_ASSERT( fc.GetNumberOfGroups() == nGroups ); + + va_list ap; + va_start(ap, nGroups); + + long cookie; + wxString name; + for ( bool cont = fc.GetFirstGroup(name, cookie); + cont; + cont = fc.GetNextGroup(name, cookie), nGroups-- ) + { + CPPUNIT_ASSERT( name == va_arg(ap, wxChar *) ); + } + + CPPUNIT_ASSERT( nGroups == 0 ); + + va_end(ap); +} + +void FileConfigTestCase::GetEntries() +{ + wxStringInputStream sis(testconfig); + wxFileConfig fc(sis); + + CheckGroupEntries(fc, _T(""), 0); + CheckGroupEntries(fc, _T("/root"), 1, _T("entry")); + CheckGroupEntries(fc, _T("/root/group1"), 0); + CheckGroupEntries(fc, _T("/root/group1/subgroup"), + 2, _T("subentry"), _T("subentry2")); +} + +void FileConfigTestCase::GetGroups() +{ + wxStringInputStream sis(testconfig); + wxFileConfig fc(sis); + + CheckGroupSubgroups(fc, _T(""), 1, _T("root")); + CheckGroupSubgroups(fc, _T("/root"), 2, _T("group1"), _T("group2")); + CheckGroupSubgroups(fc, _T("/root/group1"), 1, _T("subgroup")); + CheckGroupSubgroups(fc, _T("/root/group2"), 0); +} + +void FileConfigTestCase::HasEntry() +{ + wxStringInputStream sis(testconfig); + wxFileConfig fc(sis); + + CPPUNIT_ASSERT( !fc.HasEntry(_T("root")) ); + CPPUNIT_ASSERT( fc.HasEntry(_T("root/entry")) ); + CPPUNIT_ASSERT( fc.HasEntry(_T("/root/entry")) ); + CPPUNIT_ASSERT( fc.HasEntry(_T("root/group1/subgroup/subentry")) ); + CPPUNIT_ASSERT( !fc.HasEntry(_T("")) ); + CPPUNIT_ASSERT( !fc.HasEntry(_T("root/group1")) ); + CPPUNIT_ASSERT( !fc.HasEntry(_T("subgroup/subentry")) ); +} + +void FileConfigTestCase::HasGroup() +{ + wxStringInputStream sis(testconfig); + wxFileConfig fc(sis); + + CPPUNIT_ASSERT( fc.HasGroup(_T("root")) ); + CPPUNIT_ASSERT( fc.HasGroup(_T("root/group1")) ); + CPPUNIT_ASSERT( fc.HasGroup(_T("root/group1/subgroup")) ); + CPPUNIT_ASSERT( fc.HasGroup(_T("root/group2")) ); + CPPUNIT_ASSERT( !fc.HasGroup(_T("foot")) ); + CPPUNIT_ASSERT( !fc.HasGroup(_T("")) ); + CPPUNIT_ASSERT( !fc.HasGroup(_T("root/group")) ); + CPPUNIT_ASSERT( !fc.HasGroup(_T("root//subgroup")) ); +} + +void FileConfigTestCase::Save() +{ + wxStringInputStream sis(testconfig); + wxFileConfig fc(sis); + CPPUNIT_ASSERT( Dump(fc) == testconfig ); +} + +void FileConfigTestCase::DeleteEntry() +{ + wxStringInputStream sis(testconfig); + wxFileConfig fc(sis); + + CPPUNIT_ASSERT( !fc.DeleteEntry(_T("foo")) ); + + CPPUNIT_ASSERT( fc.DeleteEntry(_T("root/group1/subgroup/subentry")) ); + CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n") + _T("entry=value\n") + _T("[root/group1]\n") + _T("[root/group1/subgroup]\n") + _T("subentry2=subvalue2\n") + _T("[root/group2]\n") ); + + // group should be deleted now as well as it became empty + wxConfigPathChanger change(&fc, _T("root/group1/subgroup/subentry2")); + CPPUNIT_ASSERT( fc.DeleteEntry(_T("subentry2")) ); + CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n") + _T("entry=value\n") + _T("[root/group1]\n") + _T("[root/group2]\n") ); +} + +void FileConfigTestCase::DeleteGroup() +{ + wxStringInputStream sis(testconfig); + wxFileConfig fc(sis); + + CPPUNIT_ASSERT( !fc.DeleteGroup(_T("foo")) ); + + CPPUNIT_ASSERT( fc.DeleteGroup(_T("root/group1")) ); + CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n") + _T("entry=value\n") + _T("[root/group2]\n") ); + + CPPUNIT_ASSERT( fc.DeleteGroup(_T("root/group2")) ); + CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n") + _T("entry=value\n") ); + + CPPUNIT_ASSERT( fc.DeleteGroup(_T("root")) ); + CPPUNIT_ASSERT( Dump(fc).empty() ); +} + +void FileConfigTestCase::DeleteAll() +{ + wxStringInputStream sis(testconfig); + wxFileConfig fc(sis); + + CPPUNIT_ASSERT( fc.DeleteAll() ); + CPPUNIT_ASSERT( Dump(fc).empty() ); +} + +void FileConfigTestCase::RenameEntry() +{ + wxStringInputStream sis(testconfig); + wxFileConfig fc(sis); + + fc.SetPath(_T("root")); + CPPUNIT_ASSERT( fc.RenameEntry(_T("entry"), _T("newname")) ); + CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n") + _T("newname=value\n") + _T("[root/group1]\n") + _T("[root/group1/subgroup]\n") + _T("subentry=subvalue\n") + _T("subentry2=subvalue2\n") + _T("[root/group2]\n") ); + + fc.SetPath(_T("group1/subgroup")); + CPPUNIT_ASSERT( !fc.RenameEntry(_T("entry"), _T("newname")) ); + CPPUNIT_ASSERT( !fc.RenameEntry(_T("subentry"), _T("subentry2")) ); + + CPPUNIT_ASSERT( fc.RenameEntry(_T("subentry"), _T("subentry1")) ); + CPPUNIT_ASSERT( Dump(fc) == _T("[root]\n") + _T("newname=value\n") + _T("[root/group1]\n") + _T("[root/group1/subgroup]\n") + _T("subentry2=subvalue2\n") + _T("subentry1=subvalue\n") + _T("[root/group2]\n") ); +} + +void FileConfigTestCase::RenameGroup() +{ + wxStringInputStream sis(testconfig); + wxFileConfig fc(sis); + + CPPUNIT_ASSERT( fc.RenameGroup(_T("root"), _T("foot")) ); + CPPUNIT_ASSERT( Dump(fc) == _T("[foot]\n") + _T("entry=value\n") + _T("[foot/group1]\n") + _T("[foot/group1/subgroup]\n") + _T("subentry=subvalue\n") + _T("subentry2=subvalue2\n") + _T("[foot/group2]\n") ); +} + +#endif // wxUSE_FILECONFIG + diff --git a/tests/filename/filename.cpp b/tests/filename/filename.cpp deleted file mode 100644 index f91ab53ee4..0000000000 --- a/tests/filename/filename.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Name: tests/filename/filename.cpp -// Purpose: wxFileName unit test -// Author: Vadim Zeitlin -// Created: 2004-07-25 -// RCS-ID: $Id$ -// Copyright: (c) 2004 Vadim Zeitlin -/////////////////////////////////////////////////////////////////////////////// - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#ifndef WX_PRECOMP -#endif // WX_PRECOMP - -#include "wx/filename.h" - -#include "wx/cppunit.h" - -// ---------------------------------------------------------------------------- -// test data -// ---------------------------------------------------------------------------- - -static struct FileNameInfo -{ - const wxChar *fullname; - const wxChar *volume; - const wxChar *path; - const wxChar *name; - const wxChar *ext; - bool isAbsolute; - wxPathFormat format; -} filenames[] = -{ - // Unix file names - { _T("/usr/bin/ls"), _T(""), _T("/usr/bin"), _T("ls"), _T(""), true, wxPATH_UNIX }, - { _T("/usr/bin/"), _T(""), _T("/usr/bin"), _T(""), _T(""), true, wxPATH_UNIX }, - { _T("~/.zshrc"), _T(""), _T("~"), _T(".zshrc"), _T(""), true, wxPATH_UNIX }, - { _T("../../foo"), _T(""), _T("../.."), _T("foo"), _T(""), false, wxPATH_UNIX }, - { _T("foo.bar"), _T(""), _T(""), _T("foo"), _T("bar"), false, wxPATH_UNIX }, - { _T("~/foo.bar"), _T(""), _T("~"), _T("foo"), _T("bar"), true, wxPATH_UNIX }, - { _T("/foo"), _T(""), _T("/"), _T("foo"), _T(""), true, wxPATH_UNIX }, - { _T("Mahogany-0.60/foo.bar"), _T(""), _T("Mahogany-0.60"), _T("foo"), _T("bar"), false, wxPATH_UNIX }, - { _T("/tmp/wxwin.tar.bz"), _T(""), _T("/tmp"), _T("wxwin.tar"), _T("bz"), true, wxPATH_UNIX }, - - // Windows file names - { _T("foo.bar"), _T(""), _T(""), _T("foo"), _T("bar"), false, wxPATH_DOS }, - { _T("\\foo.bar"), _T(""), _T("\\"), _T("foo"), _T("bar"), false, wxPATH_DOS }, - { _T("c:foo.bar"), _T("c"), _T(""), _T("foo"), _T("bar"), false, wxPATH_DOS }, - { _T("c:\\foo.bar"), _T("c"), _T("\\"), _T("foo"), _T("bar"), true, wxPATH_DOS }, - { _T("c:\\Windows\\command.com"), _T("c"), _T("\\Windows"), _T("command"), _T("com"), true, wxPATH_DOS }, - { _T("\\\\server\\foo.bar"), _T("server"), _T("\\"), _T("foo"), _T("bar"), true, wxPATH_DOS }, - { _T("\\\\server\\dir\\foo.bar"), _T("server"), _T("\\dir"), _T("foo"), _T("bar"), true, wxPATH_DOS }, - - // wxFileName support for Mac file names is broken currently -#if 0 - // Mac file names - { _T("Volume:Dir:File"), _T("Volume"), _T("Dir"), _T("File"), _T(""), true, wxPATH_MAC }, - { _T("Volume:Dir:Subdir:File"), _T("Volume"), _T("Dir:Subdir"), _T("File"), _T(""), true, wxPATH_MAC }, - { _T("Volume:"), _T("Volume"), _T(""), _T(""), _T(""), true, wxPATH_MAC }, - { _T(":Dir:File"), _T(""), _T("Dir"), _T("File"), _T(""), false, wxPATH_MAC }, - { _T(":File.Ext"), _T(""), _T(""), _T("File"), _T(".Ext"), false, wxPATH_MAC }, - { _T("File.Ext"), _T(""), _T(""), _T("File"), _T(".Ext"), false, wxPATH_MAC }, -#endif // 0 - - // VMS file names - { _T("device:[dir1.dir2.dir3]file.txt"), _T("device"), _T("dir1.dir2.dir3"), _T("file"), _T("txt"), true, wxPATH_VMS }, - { _T("file.txt"), _T(""), _T(""), _T("file"), _T("txt"), false, wxPATH_VMS }, -}; - -// ---------------------------------------------------------------------------- -// test class -// ---------------------------------------------------------------------------- - -class FileNameTestCase : public CppUnit::TestCase -{ -public: - FileNameTestCase() { } - -private: - CPPUNIT_TEST_SUITE( FileNameTestCase ); - CPPUNIT_TEST( TestConstruction ); - CPPUNIT_TEST( TestSplit ); - CPPUNIT_TEST( TestSetPath ); - CPPUNIT_TEST_SUITE_END(); - - void TestConstruction(); - void TestSplit(); - void TestSetPath(); - - DECLARE_NO_COPY_CLASS(FileNameTestCase) -}; - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION( FileNameTestCase ); - -// also include in it's own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileNameTestCase, "FileNameTestCase" ); - -void FileNameTestCase::TestConstruction() -{ - for ( size_t n = 0; n < WXSIZEOF(filenames); n++ ) - { - const FileNameInfo& fni = filenames[n]; - - wxFileName fn(fni.fullname, fni.format); - - wxString fullname = fn.GetFullPath(fni.format); - CPPUNIT_ASSERT( fullname == fni.fullname ); - - CPPUNIT_ASSERT( fn.Normalize(wxPATH_NORM_ALL, _T(""), fni.format) ); - } -} - -void FileNameTestCase::TestSplit() -{ - for ( size_t n = 0; n < WXSIZEOF(filenames); n++ ) - { - const FileNameInfo& fni = filenames[n]; - wxString volume, path, name, ext; - wxFileName::SplitPath(fni.fullname, - &volume, &path, &name, &ext, fni.format); - - CPPUNIT_ASSERT( volume == fni.volume ); - CPPUNIT_ASSERT( path == fni.path ); - CPPUNIT_ASSERT( name == fni.name ); - CPPUNIT_ASSERT( ext == fni.ext ); - } -} - -void FileNameTestCase::TestSetPath() -{ - wxFileName fn(_T("d:\\test\\foo.bar"), wxPATH_DOS); - fn.SetPath(_T("c:\\temp"), wxPATH_DOS); - CPPUNIT_ASSERT( fn.SameAs(wxFileName(_T("c:\\temp\\foo.bar"), wxPATH_DOS)) ); - - fn = wxFileName(_T("/usr/bin/ls"), wxPATH_UNIX); - fn.SetPath(_T("/usr/local/bin"), wxPATH_UNIX); - CPPUNIT_ASSERT( fn.SameAs(wxFileName(_T("/usr/local/bin/ls"), wxPATH_UNIX)) ); -} - diff --git a/tests/filename/filenametest.cpp b/tests/filename/filenametest.cpp new file mode 100644 index 0000000000..f91ab53ee4 --- /dev/null +++ b/tests/filename/filenametest.cpp @@ -0,0 +1,148 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/filename/filename.cpp +// Purpose: wxFileName unit test +// Author: Vadim Zeitlin +// Created: 2004-07-25 +// RCS-ID: $Id$ +// Copyright: (c) 2004 Vadim Zeitlin +/////////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#endif // WX_PRECOMP + +#include "wx/filename.h" + +#include "wx/cppunit.h" + +// ---------------------------------------------------------------------------- +// test data +// ---------------------------------------------------------------------------- + +static struct FileNameInfo +{ + const wxChar *fullname; + const wxChar *volume; + const wxChar *path; + const wxChar *name; + const wxChar *ext; + bool isAbsolute; + wxPathFormat format; +} filenames[] = +{ + // Unix file names + { _T("/usr/bin/ls"), _T(""), _T("/usr/bin"), _T("ls"), _T(""), true, wxPATH_UNIX }, + { _T("/usr/bin/"), _T(""), _T("/usr/bin"), _T(""), _T(""), true, wxPATH_UNIX }, + { _T("~/.zshrc"), _T(""), _T("~"), _T(".zshrc"), _T(""), true, wxPATH_UNIX }, + { _T("../../foo"), _T(""), _T("../.."), _T("foo"), _T(""), false, wxPATH_UNIX }, + { _T("foo.bar"), _T(""), _T(""), _T("foo"), _T("bar"), false, wxPATH_UNIX }, + { _T("~/foo.bar"), _T(""), _T("~"), _T("foo"), _T("bar"), true, wxPATH_UNIX }, + { _T("/foo"), _T(""), _T("/"), _T("foo"), _T(""), true, wxPATH_UNIX }, + { _T("Mahogany-0.60/foo.bar"), _T(""), _T("Mahogany-0.60"), _T("foo"), _T("bar"), false, wxPATH_UNIX }, + { _T("/tmp/wxwin.tar.bz"), _T(""), _T("/tmp"), _T("wxwin.tar"), _T("bz"), true, wxPATH_UNIX }, + + // Windows file names + { _T("foo.bar"), _T(""), _T(""), _T("foo"), _T("bar"), false, wxPATH_DOS }, + { _T("\\foo.bar"), _T(""), _T("\\"), _T("foo"), _T("bar"), false, wxPATH_DOS }, + { _T("c:foo.bar"), _T("c"), _T(""), _T("foo"), _T("bar"), false, wxPATH_DOS }, + { _T("c:\\foo.bar"), _T("c"), _T("\\"), _T("foo"), _T("bar"), true, wxPATH_DOS }, + { _T("c:\\Windows\\command.com"), _T("c"), _T("\\Windows"), _T("command"), _T("com"), true, wxPATH_DOS }, + { _T("\\\\server\\foo.bar"), _T("server"), _T("\\"), _T("foo"), _T("bar"), true, wxPATH_DOS }, + { _T("\\\\server\\dir\\foo.bar"), _T("server"), _T("\\dir"), _T("foo"), _T("bar"), true, wxPATH_DOS }, + + // wxFileName support for Mac file names is broken currently +#if 0 + // Mac file names + { _T("Volume:Dir:File"), _T("Volume"), _T("Dir"), _T("File"), _T(""), true, wxPATH_MAC }, + { _T("Volume:Dir:Subdir:File"), _T("Volume"), _T("Dir:Subdir"), _T("File"), _T(""), true, wxPATH_MAC }, + { _T("Volume:"), _T("Volume"), _T(""), _T(""), _T(""), true, wxPATH_MAC }, + { _T(":Dir:File"), _T(""), _T("Dir"), _T("File"), _T(""), false, wxPATH_MAC }, + { _T(":File.Ext"), _T(""), _T(""), _T("File"), _T(".Ext"), false, wxPATH_MAC }, + { _T("File.Ext"), _T(""), _T(""), _T("File"), _T(".Ext"), false, wxPATH_MAC }, +#endif // 0 + + // VMS file names + { _T("device:[dir1.dir2.dir3]file.txt"), _T("device"), _T("dir1.dir2.dir3"), _T("file"), _T("txt"), true, wxPATH_VMS }, + { _T("file.txt"), _T(""), _T(""), _T("file"), _T("txt"), false, wxPATH_VMS }, +}; + +// ---------------------------------------------------------------------------- +// test class +// ---------------------------------------------------------------------------- + +class FileNameTestCase : public CppUnit::TestCase +{ +public: + FileNameTestCase() { } + +private: + CPPUNIT_TEST_SUITE( FileNameTestCase ); + CPPUNIT_TEST( TestConstruction ); + CPPUNIT_TEST( TestSplit ); + CPPUNIT_TEST( TestSetPath ); + CPPUNIT_TEST_SUITE_END(); + + void TestConstruction(); + void TestSplit(); + void TestSetPath(); + + DECLARE_NO_COPY_CLASS(FileNameTestCase) +}; + +// register in the unnamed registry so that these tests are run by default +CPPUNIT_TEST_SUITE_REGISTRATION( FileNameTestCase ); + +// also include in it's own registry so that these tests can be run alone +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileNameTestCase, "FileNameTestCase" ); + +void FileNameTestCase::TestConstruction() +{ + for ( size_t n = 0; n < WXSIZEOF(filenames); n++ ) + { + const FileNameInfo& fni = filenames[n]; + + wxFileName fn(fni.fullname, fni.format); + + wxString fullname = fn.GetFullPath(fni.format); + CPPUNIT_ASSERT( fullname == fni.fullname ); + + CPPUNIT_ASSERT( fn.Normalize(wxPATH_NORM_ALL, _T(""), fni.format) ); + } +} + +void FileNameTestCase::TestSplit() +{ + for ( size_t n = 0; n < WXSIZEOF(filenames); n++ ) + { + const FileNameInfo& fni = filenames[n]; + wxString volume, path, name, ext; + wxFileName::SplitPath(fni.fullname, + &volume, &path, &name, &ext, fni.format); + + CPPUNIT_ASSERT( volume == fni.volume ); + CPPUNIT_ASSERT( path == fni.path ); + CPPUNIT_ASSERT( name == fni.name ); + CPPUNIT_ASSERT( ext == fni.ext ); + } +} + +void FileNameTestCase::TestSetPath() +{ + wxFileName fn(_T("d:\\test\\foo.bar"), wxPATH_DOS); + fn.SetPath(_T("c:\\temp"), wxPATH_DOS); + CPPUNIT_ASSERT( fn.SameAs(wxFileName(_T("c:\\temp\\foo.bar"), wxPATH_DOS)) ); + + fn = wxFileName(_T("/usr/bin/ls"), wxPATH_UNIX); + fn.SetPath(_T("/usr/local/bin"), wxPATH_UNIX); + CPPUNIT_ASSERT( fn.SameAs(wxFileName(_T("/usr/local/bin/ls"), wxPATH_UNIX)) ); +} + diff --git a/tests/filesys/filesys.cpp b/tests/filesys/filesys.cpp deleted file mode 100644 index 90ade21d31..0000000000 --- a/tests/filesys/filesys.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Name: tests/filesys/filesys.cpp -// Purpose: wxFileSystem unit test -// Author: Vaclav Slavik -// Created: 2004-03-28 -// RCS-ID: $Id$ -// Copyright: (c) 2004 Vaclav Slavik -/////////////////////////////////////////////////////////////////////////////// - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif // WX_PRECOMP - -#include "wx/filesys.h" - -#include "wx/cppunit.h" - -#if wxUSE_FILESYSTEM - -// ---------------------------------------------------------------------------- -// helpers -// ---------------------------------------------------------------------------- - -// a hack to let us use wxFileSystemHandler's protected methods: -class UrlTester : public wxFileSystemHandler -{ -public: - UrlTester() : wxFileSystemHandler() {} - - wxString Protocol(const wxString& p) { return GetProtocol(p); } - wxString LeftLocation(const wxString& p) { return GetLeftLocation(p); } - wxString RightLocation(const wxString& p) { return GetRightLocation(p); } - wxString Anchor(const wxString& p) { return GetAnchor(p); } - - bool CanOpen(const wxString& WXUNUSED(url)) { return false; } - wxFSFile *OpenFile(wxFileSystem& WXUNUSED(fs), - const wxString& WXUNUSED(url)) { return NULL; } - - -}; - - -// ---------------------------------------------------------------------------- -// test class -// ---------------------------------------------------------------------------- - -class FileSystemTestCase : public CppUnit::TestCase -{ -public: - FileSystemTestCase() { } - -private: - CPPUNIT_TEST_SUITE( FileSystemTestCase ); - CPPUNIT_TEST( UrlParsing ); - CPPUNIT_TEST( FileNameToUrlConversion ); - CPPUNIT_TEST_SUITE_END(); - - void UrlParsing(); - void FileNameToUrlConversion(); - - DECLARE_NO_COPY_CLASS(FileSystemTestCase) -}; - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION( FileSystemTestCase ); - -// also include in it's own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileSystemTestCase, "FileSystemTestCase" ); - -void FileSystemTestCase::UrlParsing() -{ - static const struct Data - { - const wxChar *url; - const wxChar *protocol, *left, *right, *anchor; - } data[] = - { - // simple case: - { _T("http://www.root.cz/index.html"), - _T("http"), _T(""), _T("//www.root.cz/index.html"), _T("")}, - // anchors: - { _T("http://www.root.cz/index.html#lbl"), - _T("http"), _T(""), _T("//www.root.cz/index.html"), _T("lbl")}, - // file is default protocol: - { _T("testfile.html"), - _T("file"), _T(""), _T("testfile.html"), _T("")}, - // stacked protocols: - { _T("file:myzipfile.zip#zip:index.htm"), - _T("zip"), _T("file:myzipfile.zip"), _T("index.htm"), _T("")}, - // changes to ':' parsing often break things: - { _T("file:a#b:foo"), - _T("b"), _T("file:a"), _T("foo"), _T("")} - }; - - UrlTester tst; - for ( size_t n = 0; n < WXSIZEOF(data); n++ ) - { - const Data& d = data[n]; - CPPUNIT_ASSERT( tst.Protocol(d.url) == d.protocol ); - CPPUNIT_ASSERT( tst.LeftLocation(d.url) == d.left ); - CPPUNIT_ASSERT( tst.RightLocation(d.url) == d.right ); - CPPUNIT_ASSERT( tst.Anchor(d.url) == d.anchor ); - } -} - -void FileSystemTestCase::FileNameToUrlConversion() -{ -#ifdef __WINDOWS__ - wxFileName fn1(_T("\\\\server\\share\\path\\to\\file")); - wxString url1 = wxFileSystem::FileNameToURL(fn1); - - CPPUNIT_ASSERT( fn1.SameAs(wxFileSystem::URLToFileName(url1)) ); -#endif -} - -#endif // wxUSE_FILESYSTEM diff --git a/tests/filesys/filesystest.cpp b/tests/filesys/filesystest.cpp new file mode 100644 index 0000000000..90ade21d31 --- /dev/null +++ b/tests/filesys/filesystest.cpp @@ -0,0 +1,126 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/filesys/filesys.cpp +// Purpose: wxFileSystem unit test +// Author: Vaclav Slavik +// Created: 2004-03-28 +// RCS-ID: $Id$ +// Copyright: (c) 2004 Vaclav Slavik +/////////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif // WX_PRECOMP + +#include "wx/filesys.h" + +#include "wx/cppunit.h" + +#if wxUSE_FILESYSTEM + +// ---------------------------------------------------------------------------- +// helpers +// ---------------------------------------------------------------------------- + +// a hack to let us use wxFileSystemHandler's protected methods: +class UrlTester : public wxFileSystemHandler +{ +public: + UrlTester() : wxFileSystemHandler() {} + + wxString Protocol(const wxString& p) { return GetProtocol(p); } + wxString LeftLocation(const wxString& p) { return GetLeftLocation(p); } + wxString RightLocation(const wxString& p) { return GetRightLocation(p); } + wxString Anchor(const wxString& p) { return GetAnchor(p); } + + bool CanOpen(const wxString& WXUNUSED(url)) { return false; } + wxFSFile *OpenFile(wxFileSystem& WXUNUSED(fs), + const wxString& WXUNUSED(url)) { return NULL; } + + +}; + + +// ---------------------------------------------------------------------------- +// test class +// ---------------------------------------------------------------------------- + +class FileSystemTestCase : public CppUnit::TestCase +{ +public: + FileSystemTestCase() { } + +private: + CPPUNIT_TEST_SUITE( FileSystemTestCase ); + CPPUNIT_TEST( UrlParsing ); + CPPUNIT_TEST( FileNameToUrlConversion ); + CPPUNIT_TEST_SUITE_END(); + + void UrlParsing(); + void FileNameToUrlConversion(); + + DECLARE_NO_COPY_CLASS(FileSystemTestCase) +}; + +// register in the unnamed registry so that these tests are run by default +CPPUNIT_TEST_SUITE_REGISTRATION( FileSystemTestCase ); + +// also include in it's own registry so that these tests can be run alone +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileSystemTestCase, "FileSystemTestCase" ); + +void FileSystemTestCase::UrlParsing() +{ + static const struct Data + { + const wxChar *url; + const wxChar *protocol, *left, *right, *anchor; + } data[] = + { + // simple case: + { _T("http://www.root.cz/index.html"), + _T("http"), _T(""), _T("//www.root.cz/index.html"), _T("")}, + // anchors: + { _T("http://www.root.cz/index.html#lbl"), + _T("http"), _T(""), _T("//www.root.cz/index.html"), _T("lbl")}, + // file is default protocol: + { _T("testfile.html"), + _T("file"), _T(""), _T("testfile.html"), _T("")}, + // stacked protocols: + { _T("file:myzipfile.zip#zip:index.htm"), + _T("zip"), _T("file:myzipfile.zip"), _T("index.htm"), _T("")}, + // changes to ':' parsing often break things: + { _T("file:a#b:foo"), + _T("b"), _T("file:a"), _T("foo"), _T("")} + }; + + UrlTester tst; + for ( size_t n = 0; n < WXSIZEOF(data); n++ ) + { + const Data& d = data[n]; + CPPUNIT_ASSERT( tst.Protocol(d.url) == d.protocol ); + CPPUNIT_ASSERT( tst.LeftLocation(d.url) == d.left ); + CPPUNIT_ASSERT( tst.RightLocation(d.url) == d.right ); + CPPUNIT_ASSERT( tst.Anchor(d.url) == d.anchor ); + } +} + +void FileSystemTestCase::FileNameToUrlConversion() +{ +#ifdef __WINDOWS__ + wxFileName fn1(_T("\\\\server\\share\\path\\to\\file")); + wxString url1 = wxFileSystem::FileNameToURL(fn1); + + CPPUNIT_ASSERT( fn1.SameAs(wxFileSystem::URLToFileName(url1)) ); +#endif +} + +#endif // wxUSE_FILESYSTEM diff --git a/tests/fontmap/fontmap.cpp b/tests/fontmap/fontmap.cpp deleted file mode 100644 index b267f0d04e..0000000000 --- a/tests/fontmap/fontmap.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Name: tests/fontmap/fontmap.cpp -// Purpose: wxFontMapper unit test -// Author: Vadim Zeitlin -// Created: 14.02.04 -// RCS-ID: $Id$ -// Copyright: (c) 2003 TT-Solutions -/////////////////////////////////////////////////////////////////////////////// - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif // WX_PRECOMP - -#if wxUSE_FONTMAP - -#include "wx/fontmap.h" - -#include "wx/cppunit.h" - -// ---------------------------------------------------------------------------- -// test class -// ---------------------------------------------------------------------------- - -class FontMapperTestCase : public CppUnit::TestCase -{ -public: - FontMapperTestCase() { } - -private: - CPPUNIT_TEST_SUITE( FontMapperTestCase ); - CPPUNIT_TEST( NamesAndDesc ); - CPPUNIT_TEST_SUITE_END(); - - void NamesAndDesc(); - - DECLARE_NO_COPY_CLASS(FontMapperTestCase) -}; - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION( FontMapperTestCase ); - -// also include in it's own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FontMapperTestCase, "FontMapperTestCase" ); - - -void FontMapperTestCase::NamesAndDesc() -{ - static const wxChar *charsets[] = - { - // some valid charsets - _T("us-ascii" ), - _T("iso8859-1" ), - _T("iso-8859-12" ), - _T("koi8-r" ), - _T("utf-7" ), - _T("cp1250" ), - _T("windows-1252"), - - // and now some bogus ones - _T("" ), - _T("cp1249" ), - _T("iso--8859-1" ), - _T("iso-8859-19" ), - }; - - static const wxChar *names[] = - { - // some valid charsets - _T("default" ), - _T("iso-8859-1" ), - _T("iso-8859-12" ), - _T("koi8-r" ), - _T("utf-7" ), - _T("windows-1250"), - _T("windows-1252"), - - // and now some bogus ones - _T("default" ), - _T("unknown--1" ), - _T("unknown--1" ), - _T("unknown--1" ), - }; - - static const wxChar *descriptions[] = - { - // some vali charsets - _T("Default encoding" ), - _T("Western European (ISO-8859-1)" ), - _T("Indian (ISO-8859-12)" ), - _T("KOI8-R" ), - _T("Unicode 7 bit (UTF-7)" ), - _T("Windows Central European (CP 1250)"), - _T("Windows Western European (CP 1252)"), - - // and now some bogus ones - _T("Default encoding" ), - _T("Unknown encoding (-1)" ), - _T("Unknown encoding (-1)" ), - _T("Unknown encoding (-1)" ), - }; - - for ( size_t n = 0; n < WXSIZEOF(charsets); n++ ) - { - wxFontEncoding enc = wxFontMapper::Get()->CharsetToEncoding(charsets[n]); - CPPUNIT_ASSERT( wxFontMapper::Get()->GetEncodingName(enc) == names[n] ); - CPPUNIT_ASSERT( wxFontMapper::Get()->GetEncodingDescription(enc) == descriptions[n] ); - } -} - -#endif // wxUSE_FONTMAP diff --git a/tests/fontmap/fontmaptest.cpp b/tests/fontmap/fontmaptest.cpp new file mode 100644 index 0000000000..b267f0d04e --- /dev/null +++ b/tests/fontmap/fontmaptest.cpp @@ -0,0 +1,120 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/fontmap/fontmap.cpp +// Purpose: wxFontMapper unit test +// Author: Vadim Zeitlin +// Created: 14.02.04 +// RCS-ID: $Id$ +// Copyright: (c) 2003 TT-Solutions +/////////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif // WX_PRECOMP + +#if wxUSE_FONTMAP + +#include "wx/fontmap.h" + +#include "wx/cppunit.h" + +// ---------------------------------------------------------------------------- +// test class +// ---------------------------------------------------------------------------- + +class FontMapperTestCase : public CppUnit::TestCase +{ +public: + FontMapperTestCase() { } + +private: + CPPUNIT_TEST_SUITE( FontMapperTestCase ); + CPPUNIT_TEST( NamesAndDesc ); + CPPUNIT_TEST_SUITE_END(); + + void NamesAndDesc(); + + DECLARE_NO_COPY_CLASS(FontMapperTestCase) +}; + +// register in the unnamed registry so that these tests are run by default +CPPUNIT_TEST_SUITE_REGISTRATION( FontMapperTestCase ); + +// also include in it's own registry so that these tests can be run alone +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FontMapperTestCase, "FontMapperTestCase" ); + + +void FontMapperTestCase::NamesAndDesc() +{ + static const wxChar *charsets[] = + { + // some valid charsets + _T("us-ascii" ), + _T("iso8859-1" ), + _T("iso-8859-12" ), + _T("koi8-r" ), + _T("utf-7" ), + _T("cp1250" ), + _T("windows-1252"), + + // and now some bogus ones + _T("" ), + _T("cp1249" ), + _T("iso--8859-1" ), + _T("iso-8859-19" ), + }; + + static const wxChar *names[] = + { + // some valid charsets + _T("default" ), + _T("iso-8859-1" ), + _T("iso-8859-12" ), + _T("koi8-r" ), + _T("utf-7" ), + _T("windows-1250"), + _T("windows-1252"), + + // and now some bogus ones + _T("default" ), + _T("unknown--1" ), + _T("unknown--1" ), + _T("unknown--1" ), + }; + + static const wxChar *descriptions[] = + { + // some vali charsets + _T("Default encoding" ), + _T("Western European (ISO-8859-1)" ), + _T("Indian (ISO-8859-12)" ), + _T("KOI8-R" ), + _T("Unicode 7 bit (UTF-7)" ), + _T("Windows Central European (CP 1250)"), + _T("Windows Western European (CP 1252)"), + + // and now some bogus ones + _T("Default encoding" ), + _T("Unknown encoding (-1)" ), + _T("Unknown encoding (-1)" ), + _T("Unknown encoding (-1)" ), + }; + + for ( size_t n = 0; n < WXSIZEOF(charsets); n++ ) + { + wxFontEncoding enc = wxFontMapper::Get()->CharsetToEncoding(charsets[n]); + CPPUNIT_ASSERT( wxFontMapper::Get()->GetEncodingName(enc) == names[n] ); + CPPUNIT_ASSERT( wxFontMapper::Get()->GetEncodingDescription(enc) == descriptions[n] ); + } +} + +#endif // wxUSE_FONTMAP diff --git a/tests/formatconverter/formatconverter.cpp b/tests/formatconverter/formatconverter.cpp deleted file mode 100644 index 0893dd3ee8..0000000000 --- a/tests/formatconverter/formatconverter.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Name: tests/formatconverter/formatconverter.cpp -// Purpose: Test wxFormatConverter -// Author: Mike Wetherell -// RCS-ID: $Id$ -// Copyright: (c) 2004 Mike Wetherell -// Licence: wxWidgets licence -/////////////////////////////////////////////////////////////////////////////// - -// -// Notes: -// -// The conversions wxFormatConverter currently does are as follows: -// -// %s, %lS -> %ls -// %S, %hS -> %s -// %c, %lC -> %lc -// %C, %hC -> %c -// -// %hs and %hc stay the same. -// -// %S and %C aren't actually in the ISO C or C++ standards, but they can be -// avoided when writing portable code. -// -// Nor are %hs or %hc in the standards, which means wxWidgets currently doesn't -// have a specifier for 'char' types that is ok for all builds and platforms. -// -// The effect of using %hs/%hc is undefined, though RTLs are quite likely -// to just ignore the 'h', so maybe it works as required even though it's -// not legal. -// -// I've put in some checks, such as this which will flag up any platforms -// where this is not the case: -// -// CPPUNIT_ASSERT(wxString::Format(_T("%hs"), "test") == _T("test")); -// - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include "wx/cppunit.h" - -// wxFormatConverter can only be tested in a Unicode non-Windows debug build -// -#if defined(wxNEED_PRINTF_CONVERSION) && defined(__WXDEBUG__) -#define CAN_TEST -extern wxString wxConvertFormat(const wxChar *format); -#endif - -using namespace std; -using namespace CppUnit; - - -/////////////////////////////////////////////////////////////////////////////// -// The test case -// -// wxFormatConverter only changes %s, %c, %S and %C, all others are treated -// equally, therefore it is enough to choose just one other for testing, %d -// will do. - -class FormatConverterTestCase : public TestCase -{ - CPPUNIT_TEST_SUITE(FormatConverterTestCase); - CPPUNIT_TEST(format_d); - CPPUNIT_TEST(format_hd); - CPPUNIT_TEST(format_ld); - CPPUNIT_TEST(format_s); - CPPUNIT_TEST(format_hs); - CPPUNIT_TEST(format_ls); - CPPUNIT_TEST(format_c); - CPPUNIT_TEST(format_hc); - CPPUNIT_TEST(format_lc); -#ifdef CAN_TEST - CPPUNIT_TEST(format_S); - CPPUNIT_TEST(format_hS); - CPPUNIT_TEST(format_lS); - CPPUNIT_TEST(format_C); - CPPUNIT_TEST(format_hC); - CPPUNIT_TEST(format_lC); - CPPUNIT_TEST(testLonger); -#endif - CPPUNIT_TEST_SUITE_END(); - - void format_d(); - void format_hd(); - void format_ld(); - void format_s(); - void format_hs(); - void format_ls(); - void format_c(); - void format_hc(); - void format_lc(); - -#ifdef CAN_TEST - void format_S(); - void format_hS(); - void format_lS(); - void format_C(); - void format_hC(); - void format_lC(); - void testLonger(); - - void doTest(const wxChar *input, const wxChar *expected); - void check(const wxString& input, const wxString& expected); -#endif -}; - -void FormatConverterTestCase::format_d() -{ -#ifdef CAN_TEST - doTest(_T("d"), _T("d")); -#endif - CPPUNIT_ASSERT(wxString::Format(_T("%d"), 255) == _T("255")); - CPPUNIT_ASSERT(wxString::Format(_T("%05d"), 255) == _T("00255")); - CPPUNIT_ASSERT(wxString::Format(_T("% 5d"), 255) == _T(" 255")); - CPPUNIT_ASSERT(wxString::Format(_T("% 5d"), -255) == _T(" -255")); - CPPUNIT_ASSERT(wxString::Format(_T("%-5d"), -255) == _T("-255 ")); - CPPUNIT_ASSERT(wxString::Format(_T("%+5d"), 255) == _T(" +255")); - CPPUNIT_ASSERT(wxString::Format(_T("%*d"), 5, 255) == _T(" 255")); -} - -void FormatConverterTestCase::format_hd() -{ -#ifdef CAN_TEST - doTest(_T("hd"), _T("hd")); -#endif - short s = 32767; - CPPUNIT_ASSERT(wxString::Format(_T("%hd"), s) == _T("32767")); -} - -void FormatConverterTestCase::format_ld() -{ -#ifdef CAN_TEST - doTest(_T("ld"), _T("ld")); -#endif - long l = 2147483647L; - CPPUNIT_ASSERT(wxString::Format(_T("%ld"), l) == _T("2147483647")); -} - -void FormatConverterTestCase::format_s() -{ -#ifdef CAN_TEST - doTest(_T("s"), _T("ls")); -#endif - CPPUNIT_ASSERT(wxString::Format(_T("%s!"), _T("test")) == _T("test!")); - CPPUNIT_ASSERT(wxString::Format(_T("%6s!"), _T("test")) == _T(" test!")); - CPPUNIT_ASSERT(wxString::Format(_T("%-6s!"), _T("test")) == _T("test !")); - CPPUNIT_ASSERT(wxString::Format(_T("%.6s!"), _T("test")) == _T("test!")); - CPPUNIT_ASSERT(wxString::Format(_T("%6.4s!"), _T("testing")) == _T(" test!")); -} - -void FormatConverterTestCase::format_hs() -{ -#ifdef CAN_TEST - doTest(_T("hs"), _T("hs")); -#endif - CPPUNIT_ASSERT(wxString::Format(wxString(_T("%hs!")), "test") == _T("test!")); - CPPUNIT_ASSERT(wxString::Format(wxString(_T("%6hs!")), "test") == _T(" test!")); - CPPUNIT_ASSERT(wxString::Format(wxString(_T("%-6hs!")), "test") == _T("test !")); - CPPUNIT_ASSERT(wxString::Format(wxString(_T("%.6hs!")), "test") == _T("test!")); - CPPUNIT_ASSERT(wxString::Format(wxString(_T("%6.4hs!")), "testing") == _T(" test!")); -} - -void FormatConverterTestCase::format_ls() -{ -#ifdef CAN_TEST - doTest(_T("ls"), _T("ls")); -#endif - CPPUNIT_ASSERT(wxString::Format(_T("%ls!"), L"test") == _T("test!")); - CPPUNIT_ASSERT(wxString::Format(_T("%6ls!"), L"test") == _T(" test!")); - CPPUNIT_ASSERT(wxString::Format(_T("%-6ls!"), L"test") == _T("test !")); - CPPUNIT_ASSERT(wxString::Format(_T("%.6ls!"), L"test") == _T("test!")); - CPPUNIT_ASSERT(wxString::Format(_T("%6.4ls!"), L"testing") == _T(" test!")); -} - -void FormatConverterTestCase::format_c() -{ -#ifdef CAN_TEST - doTest(_T("c"), _T("lc")); -#endif - CPPUNIT_ASSERT(wxString::Format(_T("%c"), _T('x')) == _T("x")); - CPPUNIT_ASSERT(wxString::Format(_T("%2c"), _T('x')) == _T(" x")); - CPPUNIT_ASSERT(wxString::Format(_T("%-2c"), _T('x')) == _T("x ")); -} - -void FormatConverterTestCase::format_hc() -{ -#ifdef CAN_TEST - doTest(_T("hc"), _T("hc")); -#endif - CPPUNIT_ASSERT(wxString::Format(wxString(_T("%hc")), 'x') == _T("x")); - CPPUNIT_ASSERT(wxString::Format(wxString(_T("%2hc")), 'x') == _T(" x")); - CPPUNIT_ASSERT(wxString::Format(wxString(_T("%-2hc")), 'x') == _T("x ")); -} - -void FormatConverterTestCase::format_lc() -{ -#ifdef CAN_TEST - doTest(_T("lc"), _T("lc")); -#endif - CPPUNIT_ASSERT(wxString::Format(_T("%lc"), L'x') == _T("x")); - CPPUNIT_ASSERT(wxString::Format(_T("%2lc"), L'x') == _T(" x")); - CPPUNIT_ASSERT(wxString::Format(_T("%-2lc"), L'x') == _T("x ")); -} - -#ifdef CAN_TEST - -void FormatConverterTestCase::format_S() { doTest(_T("S"), _T("s")); } -void FormatConverterTestCase::format_hS() { doTest(_T("hS"), _T("s")); } -void FormatConverterTestCase::format_lS() { doTest(_T("lS"), _T("ls")); } - -void FormatConverterTestCase::format_C() { doTest(_T("C"), _T("c")); } -void FormatConverterTestCase::format_hC() { doTest(_T("hC"), _T("c")); } -void FormatConverterTestCase::format_lC() { doTest(_T("lC"), _T("lc")); } - -// It's possible that although a format converts correctly alone, it leaves -// the converter in a bad state that will affect subsequent formats, so -// check with a selection of longer patterns. -// -void FormatConverterTestCase::testLonger() -{ - struct { - const wxChar *input; - const wxChar *expected; - } formats[] = { - { _T("%d"), _T("%d"), }, - { _T("%*hd"), _T("%*hd") }, - { _T("%.4ld"), _T("%.4ld") }, - { _T("%-.*s"), _T("%-.*ls") }, - { _T("%.*hs"), _T("%.*hs"), }, - { _T("%-.9ls"), _T("%-.9ls") }, - { _T("%-*c"), _T("%-*lc") }, - { _T("%3hc"), _T("%3hc") }, - { _T("%-5lc"), _T("%-5lc") } - }; - size_t i, j; - - // exclude patterns that don't translate correctly alone from the test - for (i = 0; i < WXSIZEOF(formats); i++) - if (wxConvertFormat(formats[i].input) != formats[i].expected) - formats[i].input = NULL; - - // test all possible pairs of the above patterns - for (i = 0; i < WXSIZEOF(formats); i++) { - if (formats[i].input) { - wxString input(formats[i].input); - wxString expected(formats[i].expected); - - for (j = 0; j < WXSIZEOF(formats); j++) - if (formats[j].input) - check(input + formats[j].input, - expected + formats[j].expected); - } - } -} - -void FormatConverterTestCase::doTest(const wxChar *input, - const wxChar *expected) -{ - static const wxChar *flag_width[] = - { _T(""), _T("*"), _T("10"), _T("-*"), _T("-10"), NULL }; - static const wxChar *precision[] = - { _T(""), _T(".*"), _T(".10"), NULL }; - static const wxChar *empty[] = - { _T(""), NULL }; - - // no precision for %c or %C - const wxChar **precs = wxTolower(input[wxStrlen(input)-1]) == _T('c') ? - empty : precision; - - wxString fmt(_T("%")); - - // try the test for a variety of combinations of flag, width and precision - for (const wxChar **prec = precs; *prec; prec++) - for (const wxChar **width = flag_width; *width; width++) - check(fmt + *width + *prec + input, - fmt + *width + *prec + expected); -} - -void FormatConverterTestCase::check(const wxString& input, - const wxString& expected) -{ - wxString result = wxConvertFormat(input); - wxString msg = _T("input: '") + input + - _T("', result: '") + result + - _T("', expected: '") + expected + _T("'"); - CPPUNIT_ASSERT_MESSAGE(string(msg.mb_str()), result == expected); -} - -#endif // CAN_TEST - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION(FormatConverterTestCase); - -// also include in it's own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(FormatConverterTestCase, - "FormatConverterTestCase"); - diff --git a/tests/formatconverter/formatconvertertest.cpp b/tests/formatconverter/formatconvertertest.cpp new file mode 100644 index 0000000000..0893dd3ee8 --- /dev/null +++ b/tests/formatconverter/formatconvertertest.cpp @@ -0,0 +1,307 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/formatconverter/formatconverter.cpp +// Purpose: Test wxFormatConverter +// Author: Mike Wetherell +// RCS-ID: $Id$ +// Copyright: (c) 2004 Mike Wetherell +// Licence: wxWidgets licence +/////////////////////////////////////////////////////////////////////////////// + +// +// Notes: +// +// The conversions wxFormatConverter currently does are as follows: +// +// %s, %lS -> %ls +// %S, %hS -> %s +// %c, %lC -> %lc +// %C, %hC -> %c +// +// %hs and %hc stay the same. +// +// %S and %C aren't actually in the ISO C or C++ standards, but they can be +// avoided when writing portable code. +// +// Nor are %hs or %hc in the standards, which means wxWidgets currently doesn't +// have a specifier for 'char' types that is ok for all builds and platforms. +// +// The effect of using %hs/%hc is undefined, though RTLs are quite likely +// to just ignore the 'h', so maybe it works as required even though it's +// not legal. +// +// I've put in some checks, such as this which will flag up any platforms +// where this is not the case: +// +// CPPUNIT_ASSERT(wxString::Format(_T("%hs"), "test") == _T("test")); +// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +// for all others, include the necessary headers +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif + +#include "wx/cppunit.h" + +// wxFormatConverter can only be tested in a Unicode non-Windows debug build +// +#if defined(wxNEED_PRINTF_CONVERSION) && defined(__WXDEBUG__) +#define CAN_TEST +extern wxString wxConvertFormat(const wxChar *format); +#endif + +using namespace std; +using namespace CppUnit; + + +/////////////////////////////////////////////////////////////////////////////// +// The test case +// +// wxFormatConverter only changes %s, %c, %S and %C, all others are treated +// equally, therefore it is enough to choose just one other for testing, %d +// will do. + +class FormatConverterTestCase : public TestCase +{ + CPPUNIT_TEST_SUITE(FormatConverterTestCase); + CPPUNIT_TEST(format_d); + CPPUNIT_TEST(format_hd); + CPPUNIT_TEST(format_ld); + CPPUNIT_TEST(format_s); + CPPUNIT_TEST(format_hs); + CPPUNIT_TEST(format_ls); + CPPUNIT_TEST(format_c); + CPPUNIT_TEST(format_hc); + CPPUNIT_TEST(format_lc); +#ifdef CAN_TEST + CPPUNIT_TEST(format_S); + CPPUNIT_TEST(format_hS); + CPPUNIT_TEST(format_lS); + CPPUNIT_TEST(format_C); + CPPUNIT_TEST(format_hC); + CPPUNIT_TEST(format_lC); + CPPUNIT_TEST(testLonger); +#endif + CPPUNIT_TEST_SUITE_END(); + + void format_d(); + void format_hd(); + void format_ld(); + void format_s(); + void format_hs(); + void format_ls(); + void format_c(); + void format_hc(); + void format_lc(); + +#ifdef CAN_TEST + void format_S(); + void format_hS(); + void format_lS(); + void format_C(); + void format_hC(); + void format_lC(); + void testLonger(); + + void doTest(const wxChar *input, const wxChar *expected); + void check(const wxString& input, const wxString& expected); +#endif +}; + +void FormatConverterTestCase::format_d() +{ +#ifdef CAN_TEST + doTest(_T("d"), _T("d")); +#endif + CPPUNIT_ASSERT(wxString::Format(_T("%d"), 255) == _T("255")); + CPPUNIT_ASSERT(wxString::Format(_T("%05d"), 255) == _T("00255")); + CPPUNIT_ASSERT(wxString::Format(_T("% 5d"), 255) == _T(" 255")); + CPPUNIT_ASSERT(wxString::Format(_T("% 5d"), -255) == _T(" -255")); + CPPUNIT_ASSERT(wxString::Format(_T("%-5d"), -255) == _T("-255 ")); + CPPUNIT_ASSERT(wxString::Format(_T("%+5d"), 255) == _T(" +255")); + CPPUNIT_ASSERT(wxString::Format(_T("%*d"), 5, 255) == _T(" 255")); +} + +void FormatConverterTestCase::format_hd() +{ +#ifdef CAN_TEST + doTest(_T("hd"), _T("hd")); +#endif + short s = 32767; + CPPUNIT_ASSERT(wxString::Format(_T("%hd"), s) == _T("32767")); +} + +void FormatConverterTestCase::format_ld() +{ +#ifdef CAN_TEST + doTest(_T("ld"), _T("ld")); +#endif + long l = 2147483647L; + CPPUNIT_ASSERT(wxString::Format(_T("%ld"), l) == _T("2147483647")); +} + +void FormatConverterTestCase::format_s() +{ +#ifdef CAN_TEST + doTest(_T("s"), _T("ls")); +#endif + CPPUNIT_ASSERT(wxString::Format(_T("%s!"), _T("test")) == _T("test!")); + CPPUNIT_ASSERT(wxString::Format(_T("%6s!"), _T("test")) == _T(" test!")); + CPPUNIT_ASSERT(wxString::Format(_T("%-6s!"), _T("test")) == _T("test !")); + CPPUNIT_ASSERT(wxString::Format(_T("%.6s!"), _T("test")) == _T("test!")); + CPPUNIT_ASSERT(wxString::Format(_T("%6.4s!"), _T("testing")) == _T(" test!")); +} + +void FormatConverterTestCase::format_hs() +{ +#ifdef CAN_TEST + doTest(_T("hs"), _T("hs")); +#endif + CPPUNIT_ASSERT(wxString::Format(wxString(_T("%hs!")), "test") == _T("test!")); + CPPUNIT_ASSERT(wxString::Format(wxString(_T("%6hs!")), "test") == _T(" test!")); + CPPUNIT_ASSERT(wxString::Format(wxString(_T("%-6hs!")), "test") == _T("test !")); + CPPUNIT_ASSERT(wxString::Format(wxString(_T("%.6hs!")), "test") == _T("test!")); + CPPUNIT_ASSERT(wxString::Format(wxString(_T("%6.4hs!")), "testing") == _T(" test!")); +} + +void FormatConverterTestCase::format_ls() +{ +#ifdef CAN_TEST + doTest(_T("ls"), _T("ls")); +#endif + CPPUNIT_ASSERT(wxString::Format(_T("%ls!"), L"test") == _T("test!")); + CPPUNIT_ASSERT(wxString::Format(_T("%6ls!"), L"test") == _T(" test!")); + CPPUNIT_ASSERT(wxString::Format(_T("%-6ls!"), L"test") == _T("test !")); + CPPUNIT_ASSERT(wxString::Format(_T("%.6ls!"), L"test") == _T("test!")); + CPPUNIT_ASSERT(wxString::Format(_T("%6.4ls!"), L"testing") == _T(" test!")); +} + +void FormatConverterTestCase::format_c() +{ +#ifdef CAN_TEST + doTest(_T("c"), _T("lc")); +#endif + CPPUNIT_ASSERT(wxString::Format(_T("%c"), _T('x')) == _T("x")); + CPPUNIT_ASSERT(wxString::Format(_T("%2c"), _T('x')) == _T(" x")); + CPPUNIT_ASSERT(wxString::Format(_T("%-2c"), _T('x')) == _T("x ")); +} + +void FormatConverterTestCase::format_hc() +{ +#ifdef CAN_TEST + doTest(_T("hc"), _T("hc")); +#endif + CPPUNIT_ASSERT(wxString::Format(wxString(_T("%hc")), 'x') == _T("x")); + CPPUNIT_ASSERT(wxString::Format(wxString(_T("%2hc")), 'x') == _T(" x")); + CPPUNIT_ASSERT(wxString::Format(wxString(_T("%-2hc")), 'x') == _T("x ")); +} + +void FormatConverterTestCase::format_lc() +{ +#ifdef CAN_TEST + doTest(_T("lc"), _T("lc")); +#endif + CPPUNIT_ASSERT(wxString::Format(_T("%lc"), L'x') == _T("x")); + CPPUNIT_ASSERT(wxString::Format(_T("%2lc"), L'x') == _T(" x")); + CPPUNIT_ASSERT(wxString::Format(_T("%-2lc"), L'x') == _T("x ")); +} + +#ifdef CAN_TEST + +void FormatConverterTestCase::format_S() { doTest(_T("S"), _T("s")); } +void FormatConverterTestCase::format_hS() { doTest(_T("hS"), _T("s")); } +void FormatConverterTestCase::format_lS() { doTest(_T("lS"), _T("ls")); } + +void FormatConverterTestCase::format_C() { doTest(_T("C"), _T("c")); } +void FormatConverterTestCase::format_hC() { doTest(_T("hC"), _T("c")); } +void FormatConverterTestCase::format_lC() { doTest(_T("lC"), _T("lc")); } + +// It's possible that although a format converts correctly alone, it leaves +// the converter in a bad state that will affect subsequent formats, so +// check with a selection of longer patterns. +// +void FormatConverterTestCase::testLonger() +{ + struct { + const wxChar *input; + const wxChar *expected; + } formats[] = { + { _T("%d"), _T("%d"), }, + { _T("%*hd"), _T("%*hd") }, + { _T("%.4ld"), _T("%.4ld") }, + { _T("%-.*s"), _T("%-.*ls") }, + { _T("%.*hs"), _T("%.*hs"), }, + { _T("%-.9ls"), _T("%-.9ls") }, + { _T("%-*c"), _T("%-*lc") }, + { _T("%3hc"), _T("%3hc") }, + { _T("%-5lc"), _T("%-5lc") } + }; + size_t i, j; + + // exclude patterns that don't translate correctly alone from the test + for (i = 0; i < WXSIZEOF(formats); i++) + if (wxConvertFormat(formats[i].input) != formats[i].expected) + formats[i].input = NULL; + + // test all possible pairs of the above patterns + for (i = 0; i < WXSIZEOF(formats); i++) { + if (formats[i].input) { + wxString input(formats[i].input); + wxString expected(formats[i].expected); + + for (j = 0; j < WXSIZEOF(formats); j++) + if (formats[j].input) + check(input + formats[j].input, + expected + formats[j].expected); + } + } +} + +void FormatConverterTestCase::doTest(const wxChar *input, + const wxChar *expected) +{ + static const wxChar *flag_width[] = + { _T(""), _T("*"), _T("10"), _T("-*"), _T("-10"), NULL }; + static const wxChar *precision[] = + { _T(""), _T(".*"), _T(".10"), NULL }; + static const wxChar *empty[] = + { _T(""), NULL }; + + // no precision for %c or %C + const wxChar **precs = wxTolower(input[wxStrlen(input)-1]) == _T('c') ? + empty : precision; + + wxString fmt(_T("%")); + + // try the test for a variety of combinations of flag, width and precision + for (const wxChar **prec = precs; *prec; prec++) + for (const wxChar **width = flag_width; *width; width++) + check(fmt + *width + *prec + input, + fmt + *width + *prec + expected); +} + +void FormatConverterTestCase::check(const wxString& input, + const wxString& expected) +{ + wxString result = wxConvertFormat(input); + wxString msg = _T("input: '") + input + + _T("', result: '") + result + + _T("', expected: '") + expected + _T("'"); + CPPUNIT_ASSERT_MESSAGE(string(msg.mb_str()), result == expected); +} + +#endif // CAN_TEST + +// register in the unnamed registry so that these tests are run by default +CPPUNIT_TEST_SUITE_REGISTRATION(FormatConverterTestCase); + +// also include in it's own registry so that these tests can be run alone +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(FormatConverterTestCase, + "FormatConverterTestCase"); + diff --git a/tests/longlong/longlong.cpp b/tests/longlong/longlong.cpp deleted file mode 100644 index 93ef095150..0000000000 --- a/tests/longlong/longlong.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Name: tests/longlong/longlong.cpp -// Purpose: wxLongLong unit test -// Author: Vadim Zeitlin, Wlodzimierz ABX Skiba -// Created: 2004-04-01 -// RCS-ID: $Id$ -// Copyright: (c) 2004 Vadim Zeitlin, Wlodzimierz Skiba -/////////////////////////////////////////////////////////////////////////////// - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif // WX_PRECOMP - -#include "wx/longlong.h" -#include "wx/timer.h" - -#include "wx/cppunit.h" - -// ---------------------------------------------------------------------------- -// helpers for testing -// ---------------------------------------------------------------------------- - -// number of iterations in loops -#define ITEMS 1000 - -// make a 64 bit number from 4 16 bit ones -#define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3) - -// get a random 64 bit number -#define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand()) - -static const long testLongs[] = -{ - 0, - 1, - -1, - LONG_MAX, - LONG_MIN, - 0x1234, - -0x1234 -}; - -// ---------------------------------------------------------------------------- -// test class -// ---------------------------------------------------------------------------- - -class LongLongTestCase : public CppUnit::TestCase -{ -public: - LongLongTestCase(); - -private: - CPPUNIT_TEST_SUITE( LongLongTestCase ); - CPPUNIT_TEST( Conversion ); - CPPUNIT_TEST( Comparison ); - CPPUNIT_TEST( Addition ); - CPPUNIT_TEST( Multiplication ); - CPPUNIT_TEST( Division ); - CPPUNIT_TEST( BitOperations ); - CPPUNIT_TEST( ToString ); - CPPUNIT_TEST_SUITE_END(); - - void Conversion(); - void Comparison(); - void Addition(); - void Multiplication(); - void Division(); - void BitOperations(); - void ToString(); - - DECLARE_NO_COPY_CLASS(LongLongTestCase) -}; - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION( LongLongTestCase ); - -// also include in it's own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( LongLongTestCase, "LongLongTestCase" ); - -LongLongTestCase::LongLongTestCase() -{ - srand((unsigned)time(NULL)); -} - -void LongLongTestCase::Conversion() -{ - for ( size_t n = 0; n < ITEMS; n++ ) - { - wxLongLong a = RAND_LL(); - - wxLongLong b(a.GetHi(), a.GetLo()); - CPPUNIT_ASSERT( a == b ); - -#if wxUSE_LONGLONG_WX - wxLongLongWx c(a.GetHi(), a.GetLo()); - CPPUNIT_ASSERT( a == c ); -#endif - -#if wxUSE_LONGLONG_NATIVE - wxLongLongNative d(a.GetHi(), a.GetLo()); - CPPUNIT_ASSERT( a == d ); -#endif - } -} - -void LongLongTestCase::Comparison() -{ - static const long ls[2] = - { - 0x1234, - -0x1234, - }; - - wxLongLong lls[2]; - lls[0] = ls[0]; - lls[1] = ls[1]; - - for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ ) - { - for ( size_t m = 0; m < WXSIZEOF(lls); m++ ) - { - CPPUNIT_ASSERT( (lls[m] < testLongs[n]) == (ls[m] < testLongs[n]) ); - CPPUNIT_ASSERT( (lls[m] > testLongs[n]) == (ls[m] > testLongs[n]) ); - CPPUNIT_ASSERT( (lls[m] <= testLongs[n]) == (ls[m] <= testLongs[n]) ); - CPPUNIT_ASSERT( (lls[m] >= testLongs[n]) == (ls[m] >= testLongs[n]) ); - CPPUNIT_ASSERT( (lls[m] != testLongs[n]) == (ls[m] != testLongs[n]) ); - CPPUNIT_ASSERT( (lls[m] == testLongs[n]) == (ls[m] == testLongs[n]) ); - } - } -} - -void LongLongTestCase::Addition() -{ - for ( size_t n = 0; n < ITEMS; n++ ) - { - wxLongLong a = RAND_LL(); - wxLongLong b = RAND_LL(); - wxLongLong c = a + b; - -#if wxUSE_LONGLONG_NATIVE - wxLongLongNative a1 = a; - wxLongLongNative b1 = b; - wxLongLongNative c1 = a1 + b1; - CPPUNIT_ASSERT( c == c1 ); -#endif - -#if wxUSE_LONGLONG_WX - wxLongLongWx a2 = a; - wxLongLongWx b2 = b; - wxLongLongWx c2 = a2 + b2; - CPPUNIT_ASSERT( c == c2 ); -#endif - } -} - -void LongLongTestCase::Multiplication() -{ - for ( size_t n = 0; n < ITEMS; n++ ) - { - wxLongLong a = RAND_LL(); - wxLongLong b = RAND_LL(); - wxLongLong c = a*b; - - wxLongLong a1(a.GetHi(), a.GetLo()); - wxLongLong b1(b.GetHi(), b.GetLo()); - wxLongLong c1 = a1*b1; - CPPUNIT_ASSERT( c1 == c ); - -#if wxUSE_LONGLONG_WX - wxLongLongWx a2(a.GetHi(), a.GetLo()); - wxLongLongWx b2(b.GetHi(), b.GetLo()); - wxLongLongWx c2 = a2*b2; - CPPUNIT_ASSERT( c2 == c ); -#endif - -#if wxUSE_LONGLONG_NATIVE - wxLongLongNative a3(a.GetHi(), a.GetLo()); - wxLongLongNative b3(b.GetHi(), b.GetLo()); - wxLongLongNative c3 = a3*b3; - CPPUNIT_ASSERT( c3 == c ); -#endif - } -} - -void LongLongTestCase::Division() -{ - for ( size_t n = 0; n < ITEMS; n++ ) - { - // get a random wxLongLong (shifting by 12 the MSB ensures that the - // multiplication will not overflow) - wxLongLong a = MAKE_LL((rand() >> 12), rand(), rand(), rand()); - - // get a random (but non null) long (not wxLongLong for now) divider - long l; - do - { - l = rand(); - } - while ( !l ); - - wxLongLong q = a / l; - wxLongLong r = a % l; - - CPPUNIT_ASSERT( a == ( q * l + r ) ); - -#if wxUSE_LONGLONG_WX - wxLongLongWx a1(a.GetHi(), a.GetLo()); - wxLongLongWx q1 = a1 / l; - wxLongLongWx r1 = a1 % l; - CPPUNIT_ASSERT( q == q1 ); - CPPUNIT_ASSERT( r == r1 ); - CPPUNIT_ASSERT( a1 == ( q1 * l + r1 ) ); -#endif - -#if wxUSE_LONGLONG_NATIVE - wxLongLongNative a2(a.GetHi(), a.GetLo()); - wxLongLongNative q2 = a2 / l; - wxLongLongNative r2 = a2 % l; - CPPUNIT_ASSERT( q == q2 ); - CPPUNIT_ASSERT( r == r2 ); - CPPUNIT_ASSERT( a2 == ( q2 * l + r2 ) ); -#endif - } -} - -void LongLongTestCase::BitOperations() -{ - for ( size_t n = 0; n < ITEMS; n++ ) - { - wxLongLong a = RAND_LL(); - - for ( size_t n = 0; n < 33; n++ ) - { - wxLongLong b(a.GetHi(), a.GetLo()), c, d = b, e; - d >>= n; - c = b >> n; - CPPUNIT_ASSERT( c == d ); - d <<= n; - e = c << n; - CPPUNIT_ASSERT( d == e ); - -#if wxUSE_LONGLONG_WX - wxLongLongWx b1(a.GetHi(), a.GetLo()), c1, d1 = b1, e1; - d1 >>= n; - c1 = b1 >> n; - CPPUNIT_ASSERT( c1 == d1 ); - d1 <<= n; - e1 = c1 << n; - CPPUNIT_ASSERT( d1 == e1 ); -#endif - -#if wxUSE_LONGLONG_NATIVE - wxLongLongNative b2(a.GetHi(), a.GetLo()), c2, d2 = b2, e2; - d2 >>= n; - c2 = b2 >> n; - CPPUNIT_ASSERT( c2 == d2 ); - d2 <<= n; - e2 = c2 << n; - CPPUNIT_ASSERT( d2 == e2 ); -#endif - } - } -} - -void LongLongTestCase::ToString() -{ - wxString s1, s2; - - for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ ) - { - wxLongLong a = testLongs[n]; - s1 = wxString::Format(_T("%ld"), testLongs[n]); - s2 = a.ToString(); - CPPUNIT_ASSERT( s1 == s2 ); - -#if wxUSE_LONGLONG_WX - wxLongLongWx a1 = testLongs[n]; - s2 = a1.ToString(); - CPPUNIT_ASSERT( s1 == s2 ); -#endif - -#if wxUSE_LONGLONG_NATIVE - wxLongLongNative a2 = testLongs[n]; - s2 = a2.ToString(); - CPPUNIT_ASSERT( s1 == s2 ); -#endif - } - - wxLongLong a(0x12345678, 0x87654321); - CPPUNIT_ASSERT( a.ToString() == _T("1311768467139281697") ); - a.Negate(); - CPPUNIT_ASSERT( a.ToString() == _T("-1311768467139281697") ); - -#if wxUSE_LONGLONG_WX - wxLongLongWx a1(a.GetHi(), a.GetLo()); - CPPUNIT_ASSERT( a1.ToString() == _T("-1311768467139281697") ); - a1.Negate(); - CPPUNIT_ASSERT( a1.ToString() == _T("1311768467139281697") ); -#endif - -#if wxUSE_LONGLONG_NATIVE - wxLongLongNative a2(a.GetHi(), a.GetLo()); - CPPUNIT_ASSERT( a2.ToString() == _T("-1311768467139281697") ); - a2.Negate(); - CPPUNIT_ASSERT( a2.ToString() == _T("1311768467139281697") ); -#endif - -} - diff --git a/tests/longlong/longlongtest.cpp b/tests/longlong/longlongtest.cpp new file mode 100644 index 0000000000..93ef095150 --- /dev/null +++ b/tests/longlong/longlongtest.cpp @@ -0,0 +1,319 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/longlong/longlong.cpp +// Purpose: wxLongLong unit test +// Author: Vadim Zeitlin, Wlodzimierz ABX Skiba +// Created: 2004-04-01 +// RCS-ID: $Id$ +// Copyright: (c) 2004 Vadim Zeitlin, Wlodzimierz Skiba +/////////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif // WX_PRECOMP + +#include "wx/longlong.h" +#include "wx/timer.h" + +#include "wx/cppunit.h" + +// ---------------------------------------------------------------------------- +// helpers for testing +// ---------------------------------------------------------------------------- + +// number of iterations in loops +#define ITEMS 1000 + +// make a 64 bit number from 4 16 bit ones +#define MAKE_LL(x1, x2, x3, x4) wxLongLong((x1 << 16) | x2, (x3 << 16) | x3) + +// get a random 64 bit number +#define RAND_LL() MAKE_LL(rand(), rand(), rand(), rand()) + +static const long testLongs[] = +{ + 0, + 1, + -1, + LONG_MAX, + LONG_MIN, + 0x1234, + -0x1234 +}; + +// ---------------------------------------------------------------------------- +// test class +// ---------------------------------------------------------------------------- + +class LongLongTestCase : public CppUnit::TestCase +{ +public: + LongLongTestCase(); + +private: + CPPUNIT_TEST_SUITE( LongLongTestCase ); + CPPUNIT_TEST( Conversion ); + CPPUNIT_TEST( Comparison ); + CPPUNIT_TEST( Addition ); + CPPUNIT_TEST( Multiplication ); + CPPUNIT_TEST( Division ); + CPPUNIT_TEST( BitOperations ); + CPPUNIT_TEST( ToString ); + CPPUNIT_TEST_SUITE_END(); + + void Conversion(); + void Comparison(); + void Addition(); + void Multiplication(); + void Division(); + void BitOperations(); + void ToString(); + + DECLARE_NO_COPY_CLASS(LongLongTestCase) +}; + +// register in the unnamed registry so that these tests are run by default +CPPUNIT_TEST_SUITE_REGISTRATION( LongLongTestCase ); + +// also include in it's own registry so that these tests can be run alone +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( LongLongTestCase, "LongLongTestCase" ); + +LongLongTestCase::LongLongTestCase() +{ + srand((unsigned)time(NULL)); +} + +void LongLongTestCase::Conversion() +{ + for ( size_t n = 0; n < ITEMS; n++ ) + { + wxLongLong a = RAND_LL(); + + wxLongLong b(a.GetHi(), a.GetLo()); + CPPUNIT_ASSERT( a == b ); + +#if wxUSE_LONGLONG_WX + wxLongLongWx c(a.GetHi(), a.GetLo()); + CPPUNIT_ASSERT( a == c ); +#endif + +#if wxUSE_LONGLONG_NATIVE + wxLongLongNative d(a.GetHi(), a.GetLo()); + CPPUNIT_ASSERT( a == d ); +#endif + } +} + +void LongLongTestCase::Comparison() +{ + static const long ls[2] = + { + 0x1234, + -0x1234, + }; + + wxLongLong lls[2]; + lls[0] = ls[0]; + lls[1] = ls[1]; + + for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ ) + { + for ( size_t m = 0; m < WXSIZEOF(lls); m++ ) + { + CPPUNIT_ASSERT( (lls[m] < testLongs[n]) == (ls[m] < testLongs[n]) ); + CPPUNIT_ASSERT( (lls[m] > testLongs[n]) == (ls[m] > testLongs[n]) ); + CPPUNIT_ASSERT( (lls[m] <= testLongs[n]) == (ls[m] <= testLongs[n]) ); + CPPUNIT_ASSERT( (lls[m] >= testLongs[n]) == (ls[m] >= testLongs[n]) ); + CPPUNIT_ASSERT( (lls[m] != testLongs[n]) == (ls[m] != testLongs[n]) ); + CPPUNIT_ASSERT( (lls[m] == testLongs[n]) == (ls[m] == testLongs[n]) ); + } + } +} + +void LongLongTestCase::Addition() +{ + for ( size_t n = 0; n < ITEMS; n++ ) + { + wxLongLong a = RAND_LL(); + wxLongLong b = RAND_LL(); + wxLongLong c = a + b; + +#if wxUSE_LONGLONG_NATIVE + wxLongLongNative a1 = a; + wxLongLongNative b1 = b; + wxLongLongNative c1 = a1 + b1; + CPPUNIT_ASSERT( c == c1 ); +#endif + +#if wxUSE_LONGLONG_WX + wxLongLongWx a2 = a; + wxLongLongWx b2 = b; + wxLongLongWx c2 = a2 + b2; + CPPUNIT_ASSERT( c == c2 ); +#endif + } +} + +void LongLongTestCase::Multiplication() +{ + for ( size_t n = 0; n < ITEMS; n++ ) + { + wxLongLong a = RAND_LL(); + wxLongLong b = RAND_LL(); + wxLongLong c = a*b; + + wxLongLong a1(a.GetHi(), a.GetLo()); + wxLongLong b1(b.GetHi(), b.GetLo()); + wxLongLong c1 = a1*b1; + CPPUNIT_ASSERT( c1 == c ); + +#if wxUSE_LONGLONG_WX + wxLongLongWx a2(a.GetHi(), a.GetLo()); + wxLongLongWx b2(b.GetHi(), b.GetLo()); + wxLongLongWx c2 = a2*b2; + CPPUNIT_ASSERT( c2 == c ); +#endif + +#if wxUSE_LONGLONG_NATIVE + wxLongLongNative a3(a.GetHi(), a.GetLo()); + wxLongLongNative b3(b.GetHi(), b.GetLo()); + wxLongLongNative c3 = a3*b3; + CPPUNIT_ASSERT( c3 == c ); +#endif + } +} + +void LongLongTestCase::Division() +{ + for ( size_t n = 0; n < ITEMS; n++ ) + { + // get a random wxLongLong (shifting by 12 the MSB ensures that the + // multiplication will not overflow) + wxLongLong a = MAKE_LL((rand() >> 12), rand(), rand(), rand()); + + // get a random (but non null) long (not wxLongLong for now) divider + long l; + do + { + l = rand(); + } + while ( !l ); + + wxLongLong q = a / l; + wxLongLong r = a % l; + + CPPUNIT_ASSERT( a == ( q * l + r ) ); + +#if wxUSE_LONGLONG_WX + wxLongLongWx a1(a.GetHi(), a.GetLo()); + wxLongLongWx q1 = a1 / l; + wxLongLongWx r1 = a1 % l; + CPPUNIT_ASSERT( q == q1 ); + CPPUNIT_ASSERT( r == r1 ); + CPPUNIT_ASSERT( a1 == ( q1 * l + r1 ) ); +#endif + +#if wxUSE_LONGLONG_NATIVE + wxLongLongNative a2(a.GetHi(), a.GetLo()); + wxLongLongNative q2 = a2 / l; + wxLongLongNative r2 = a2 % l; + CPPUNIT_ASSERT( q == q2 ); + CPPUNIT_ASSERT( r == r2 ); + CPPUNIT_ASSERT( a2 == ( q2 * l + r2 ) ); +#endif + } +} + +void LongLongTestCase::BitOperations() +{ + for ( size_t n = 0; n < ITEMS; n++ ) + { + wxLongLong a = RAND_LL(); + + for ( size_t n = 0; n < 33; n++ ) + { + wxLongLong b(a.GetHi(), a.GetLo()), c, d = b, e; + d >>= n; + c = b >> n; + CPPUNIT_ASSERT( c == d ); + d <<= n; + e = c << n; + CPPUNIT_ASSERT( d == e ); + +#if wxUSE_LONGLONG_WX + wxLongLongWx b1(a.GetHi(), a.GetLo()), c1, d1 = b1, e1; + d1 >>= n; + c1 = b1 >> n; + CPPUNIT_ASSERT( c1 == d1 ); + d1 <<= n; + e1 = c1 << n; + CPPUNIT_ASSERT( d1 == e1 ); +#endif + +#if wxUSE_LONGLONG_NATIVE + wxLongLongNative b2(a.GetHi(), a.GetLo()), c2, d2 = b2, e2; + d2 >>= n; + c2 = b2 >> n; + CPPUNIT_ASSERT( c2 == d2 ); + d2 <<= n; + e2 = c2 << n; + CPPUNIT_ASSERT( d2 == e2 ); +#endif + } + } +} + +void LongLongTestCase::ToString() +{ + wxString s1, s2; + + for ( size_t n = 0; n < WXSIZEOF(testLongs); n++ ) + { + wxLongLong a = testLongs[n]; + s1 = wxString::Format(_T("%ld"), testLongs[n]); + s2 = a.ToString(); + CPPUNIT_ASSERT( s1 == s2 ); + +#if wxUSE_LONGLONG_WX + wxLongLongWx a1 = testLongs[n]; + s2 = a1.ToString(); + CPPUNIT_ASSERT( s1 == s2 ); +#endif + +#if wxUSE_LONGLONG_NATIVE + wxLongLongNative a2 = testLongs[n]; + s2 = a2.ToString(); + CPPUNIT_ASSERT( s1 == s2 ); +#endif + } + + wxLongLong a(0x12345678, 0x87654321); + CPPUNIT_ASSERT( a.ToString() == _T("1311768467139281697") ); + a.Negate(); + CPPUNIT_ASSERT( a.ToString() == _T("-1311768467139281697") ); + +#if wxUSE_LONGLONG_WX + wxLongLongWx a1(a.GetHi(), a.GetLo()); + CPPUNIT_ASSERT( a1.ToString() == _T("-1311768467139281697") ); + a1.Negate(); + CPPUNIT_ASSERT( a1.ToString() == _T("1311768467139281697") ); +#endif + +#if wxUSE_LONGLONG_NATIVE + wxLongLongNative a2(a.GetHi(), a.GetLo()); + CPPUNIT_ASSERT( a2.ToString() == _T("-1311768467139281697") ); + a2.Negate(); + CPPUNIT_ASSERT( a2.ToString() == _T("1311768467139281697") ); +#endif + +} + diff --git a/tests/mbconv/main.cpp b/tests/mbconv/main.cpp deleted file mode 100644 index 6c509c838d..0000000000 --- a/tests/mbconv/main.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Name: tests/mbconv/main.cpp -// Purpose: wxMBConv unit test -// Author: Vadim Zeitlin -// Created: 14.02.04 -// RCS-ID: $Id$ -// Copyright: (c) 2003 TT-Solutions -/////////////////////////////////////////////////////////////////////////////// - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif // WX_PRECOMP - -#include "wx/strconv.h" -#include "wx/string.h" - -#include "wx/cppunit.h" - -// ---------------------------------------------------------------------------- -// test class -// ---------------------------------------------------------------------------- - -class MBConvTestCase : public CppUnit::TestCase -{ -public: - MBConvTestCase() { } - -private: - CPPUNIT_TEST_SUITE( MBConvTestCase ); - CPPUNIT_TEST( WC2CP1250 ); - CPPUNIT_TEST_SUITE_END(); - - void WC2CP1250(); - - DECLARE_NO_COPY_CLASS(MBConvTestCase) -}; - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION( MBConvTestCase ); - -// also include in it's own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MBConvTestCase, "MBConvTestCase" ); - -void MBConvTestCase::WC2CP1250() -{ - static const struct Data - { - const wchar_t *wc; - const char *cp1250; - } data[] = - { - { L"hello", "hello" }, // test that it works in simplest case - { L"\xBD of \xBD is \xBC", NULL }, // this should fail as cp1250 doesn't have 1/2 - }; - - wxCSConv cs1250(wxFONTENCODING_CP1250); - for ( size_t n = 0; n < WXSIZEOF(data); n++ ) - { - const Data& d = data[n]; - if (d.cp1250) - { - CPPUNIT_ASSERT( strcmp(cs1250.cWC2MB(d.wc), d.cp1250) == 0 ); - } - else - { - CPPUNIT_ASSERT( (const char*)cs1250.cWC2MB(d.wc) == NULL ); - } - } -} diff --git a/tests/mbconv/mbconvtest.cpp b/tests/mbconv/mbconvtest.cpp new file mode 100644 index 0000000000..6c509c838d --- /dev/null +++ b/tests/mbconv/mbconvtest.cpp @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/mbconv/main.cpp +// Purpose: wxMBConv unit test +// Author: Vadim Zeitlin +// Created: 14.02.04 +// RCS-ID: $Id$ +// Copyright: (c) 2003 TT-Solutions +/////////////////////////////////////////////////////////////////////////////// + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif // WX_PRECOMP + +#include "wx/strconv.h" +#include "wx/string.h" + +#include "wx/cppunit.h" + +// ---------------------------------------------------------------------------- +// test class +// ---------------------------------------------------------------------------- + +class MBConvTestCase : public CppUnit::TestCase +{ +public: + MBConvTestCase() { } + +private: + CPPUNIT_TEST_SUITE( MBConvTestCase ); + CPPUNIT_TEST( WC2CP1250 ); + CPPUNIT_TEST_SUITE_END(); + + void WC2CP1250(); + + DECLARE_NO_COPY_CLASS(MBConvTestCase) +}; + +// register in the unnamed registry so that these tests are run by default +CPPUNIT_TEST_SUITE_REGISTRATION( MBConvTestCase ); + +// also include in it's own registry so that these tests can be run alone +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MBConvTestCase, "MBConvTestCase" ); + +void MBConvTestCase::WC2CP1250() +{ + static const struct Data + { + const wchar_t *wc; + const char *cp1250; + } data[] = + { + { L"hello", "hello" }, // test that it works in simplest case + { L"\xBD of \xBD is \xBC", NULL }, // this should fail as cp1250 doesn't have 1/2 + }; + + wxCSConv cs1250(wxFONTENCODING_CP1250); + for ( size_t n = 0; n < WXSIZEOF(data); n++ ) + { + const Data& d = data[n]; + if (d.cp1250) + { + CPPUNIT_ASSERT( strcmp(cs1250.cWC2MB(d.wc), d.cp1250) == 0 ); + } + else + { + CPPUNIT_ASSERT( (const char*)cs1250.cWC2MB(d.wc) == NULL ); + } + } +} diff --git a/tests/regex/regex.cpp b/tests/regex/regex.cpp deleted file mode 100644 index 261435e8ed..0000000000 --- a/tests/regex/regex.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Name: tests/regex/regex.cpp -// Purpose: Test the built-in regex lib and wxRegEx -// Author: Mike Wetherell -// RCS-ID: $Id$ -// Copyright: (c) 2004 Mike Wetherell -// Licence: wxWidgets licence -/////////////////////////////////////////////////////////////////////////////// - -// -// Notes: -// -// To run just one section, say wx_1, do this: -// test regex.wx_1 -// -// To run all the regex tests: -// test regex -// -// Some tests must be skipped since they use features which we do not make -// available through wxRegEx. To see the list of tests that have been skipped -// turn on verbose logging, e.g.: -// test --verbose regex -// -// The tests here are for the builtin library, tests for wxRegEx in general -// should go in wxregex.cpp -// -// The tests are generated from Henry Spencer's reg.test, additional test -// can be added in wxreg.test. These test files are then turned into a C++ -// include file 'regex.inc' (included below) using a script 'regex.pl'. -// - -// For compilers that support precompilation, includes "wx/wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -// for all others, include the necessary headers -#ifndef WX_PRECOMP - #include "wx/wx.h" -#endif - -#include "wx/regex.h" -#include "wx/cppunit.h" -#include - -using namespace std; -using namespace CppUnit; - -// many of the tests are specific to the builtin regex lib, so only attempts -// to do them when using the builtin regex lib. -// -#ifdef wxHAS_REGEX_ADVANCED - - -/////////////////////////////////////////////////////////////////////////////// -// The test case - an instance represents a single test - -class RegExTestCase : public TestCase -{ -public: - // constructor - create a single testcase - RegExTestCase( - const string& name, - const char *mode, - const char *id, - const char *flags, - const char *pattern, - const char *data, - const vector& expected); - -protected: - // run this testcase - void runTest(); - -private: - // workers - wxString Conv(const char *str); - void parseFlags(const wxString& flags); - void doTest(int flavor); - static wxString quote(const wxString& arg); - const wxChar *convError() const { return _T(""); } - - // assertions - adds some information about the test that failed - void fail(const wxString& msg) const; - void failIf(bool condition, const wxString& msg) const - { if (condition) fail(msg); } - - // mode, id, flags, pattern, test data, expected results... - int m_mode; - wxString m_id; - wxString m_flags; - wxString m_pattern; - wxString m_data; - wxArrayString m_expected; - - // the flag decoded - int m_compileFlags; - int m_matchFlags; - bool m_basic; - bool m_extended; - bool m_advanced; -}; - -// constructor - throws Exception on failure -// -RegExTestCase::RegExTestCase( - const string& name, - const char *mode, - const char *id, - const char *flags, - const char *pattern, - const char *data, - const vector& expected) - : - TestCase(name), - m_mode(mode[0]), - m_id(Conv(id)), - m_flags(Conv(flags)), - m_pattern(Conv(pattern)), - m_data(Conv(data)), - m_compileFlags(0), - m_matchFlags(0), - m_basic(false), - m_extended(false), - m_advanced(false) -{ - bool badconv = m_pattern == convError() || m_data == convError(); - vector::const_iterator it; - - for (it = expected.begin(); it != expected.end(); ++it) { - m_expected.push_back(Conv(*it)); - badconv = badconv || *m_expected.rbegin() == convError(); - } - - failIf(badconv, _T("cannot convert to default character encoding")); - - // the flags need further parsing... - parseFlags(m_flags); - -#ifndef wxHAS_REGEX_ADVANCED - failIf(!m_basic && !m_extended, _T("advanced regexs not available")); -#endif -} - -int wxWcscmp(const wchar_t* s1, const wchar_t* s2) -{ - size_t nLen1 = wxWcslen(s1); - size_t nLen2 = wxWcslen(s2); - - if (nLen1 != nLen2) - return nLen1 - nLen2; - - return wxMemcmp(s1, s2, nLen1); -} - -// convert a string from UTF8 to the internal encoding -// -wxString RegExTestCase::Conv(const char *str) -{ - const wxWCharBuffer wstr = wxConvUTF8.cMB2WC(str); - const wxWC2WXbuf buf = wxConvCurrent->cWC2WX(wstr); - - if (!buf || wxWcscmp(wxConvCurrent->cWX2WC(buf), wstr) != 0) - return convError(); - else - return buf; -} - -// Parse flags -// -void RegExTestCase::parseFlags(const wxString& flags) -{ - for (const wxChar *p = flags; *p; p++) { - switch (*p) { - // noop - case '-': break; - - // we don't fully support these flags, but they don't stop us - // checking for success of failure of the match, so treat as noop - case 'A': case 'B': case 'E': case 'H': - case 'I': case 'L': case 'M': case 'N': - case 'P': case 'Q': case 'R': case 'S': - case 'T': case 'U': case '%': - break; - - // match options - case '^': m_matchFlags |= wxRE_NOTBOL; break; - case '$': m_matchFlags |= wxRE_NOTEOL; break; -#if wxUSE_UNICODE - case '*': break; -#endif - // compile options - case '&': m_advanced = m_basic = true; break; - case 'b': m_basic = true; break; - case 'e': m_extended = true; break; - case 'i': m_compileFlags |= wxRE_ICASE; break; - case 'o': m_compileFlags |= wxRE_NOSUB; break; - case 'n': m_compileFlags |= wxRE_NEWLINE; break; - case 't': if (strchr("ep", m_mode)) break; // else fall through... - - // anything else we must skip the test - default: - fail(wxString::Format( - _T("requires unsupported flag '%c'"), *p)); - } - } -} - -// Try test for all flavours of expression specified -// -void RegExTestCase::runTest() -{ - if (m_basic) - doTest(wxRE_BASIC); - if (m_extended) - doTest(wxRE_EXTENDED); -#ifdef wxHAS_REGEX_ADVANCED - if (m_advanced || (!m_basic && !m_extended)) - doTest(wxRE_ADVANCED); -#endif -} - -// Try the test for a single flavour of expression -// -void RegExTestCase::doTest(int flavor) -{ - wxRegEx re(m_pattern, m_compileFlags | flavor); - - // 'e' - test that the pattern fails to compile - if (m_mode == 'e') { - failIf(re.IsValid(), _T("compile succeeded (should fail)")); - return; - } - failIf(!re.IsValid(), _T("compile failed")); - - bool matches = re.Matches(m_data, m_matchFlags); - - // 'f' or 'p' - test that the pattern does not match - if (m_mode == 'f' || m_mode == 'p') { - failIf(matches, _T("match succeeded (should fail)")); - return; - } - - // otherwise 'm' or 'i' - test the pattern does match - failIf(!matches, _T("match failed")); - - if (m_compileFlags & wxRE_NOSUB) - return; - - // check wxRegEx has correctly counted the number of subexpressions - failIf(m_expected.size() != re.GetMatchCount(), - wxString::Format(_T("GetMatchCount() == %d, expected %d"), - re.GetMatchCount(), m_expected.size())); - - wxString result; - size_t start, len; - - for (size_t i = 0; i < m_expected.size(); i++) { - failIf(!re.GetMatch(&start, &len, i), wxString::Format( - _T("wxRegEx::GetMatch failed for match %d"), i)); - - // m - check the match returns the strings given - if (m_mode == 'm') - if (start < INT_MAX) - result = m_data.substr(start, len); - else - result = _T(""); - - // i - check the match returns the offsets given - else if (m_mode == 'i') - if (start < INT_MAX) - result = wxString::Format(_T("%d %d"), start, start + len - 1); - else - result = _T("-1 -1"); - - failIf(result != m_expected[i], wxString::Format( - _T("match(%d) == %s, expected == %s"), i, - quote(result).c_str(), quote(m_expected[i]).c_str())); - } -} - -// assertion - adds some information about the test that failed -// -void RegExTestCase::fail(const wxString& msg) const -{ - wxString str; - wxArrayString::const_iterator it; - - str << (wxChar)m_mode << _T(" ") << m_id << _T(" ") << m_flags << _T(" ") - << quote(m_pattern) << _T(" ") << quote(m_data); - - for (it = m_expected.begin(); it != m_expected.end(); ++it) - str << _T(" ") << quote(*it); - - if (str.length() > 77) - str = str.substr(0, 74) + _T("..."); - - str << _T("\n ") << msg; - - // no lossy convs so using utf8 - CPPUNIT_FAIL(string(str.mb_str(wxConvUTF8))); -} - -// quote a string so that it can be displayed (static) -// -wxString RegExTestCase::quote(const wxString& arg) -{ - const wxChar *needEscape = _T("\a\b\t\n\v\f\r\"\\"); - const wxChar *escapes = _T("abtnvfr\"\\"); - wxString str; - - for (size_t i = 0; i < arg.length(); i++) { - wxUChar ch = arg[i]; - const wxChar *p = wxStrchr(needEscape, ch); - - if (p) - str += wxString::Format(_T("\\%c"), escapes[p - needEscape]); - else if (wxIscntrl(ch)) - str += wxString::Format(_T("\\%03o"), ch); - else - str += ch; - } - - return str.length() == arg.length() && str.find(' ') == wxString::npos ? - str : _T("\"") + str + _T("\""); -} - - -/////////////////////////////////////////////////////////////////////////////// -// Test suite - -class RegExTestSuite : public TestSuite -{ -public: - RegExTestSuite(string name) : TestSuite(name) { } - void add(const char *mode, const char *id, const char *flags, - const char *pattern, const char *data, const char *expected, ...); -}; - -// Add a testcase to the suite -// -void RegExTestSuite::add( - const char *mode, - const char *id, - const char *flags, - const char *pattern, - const char *data, - const char *expected, ...) -{ - string name = getName() + "." + id; - - vector expected_results; - va_list ap; - - for (va_start(ap, expected); expected; expected = va_arg(ap, const char *)) - expected_results.push_back(expected); - - va_end(ap); - - try { - addTest(new RegExTestCase( - name, mode, id, flags, pattern, data, expected_results)); - } - catch (Exception& e) { - wxLogInfo(wxString::Format(_T("skipping: %s\n %s\n"), - wxString(name.c_str(), wxConvUTF8).c_str(), - wxString(e.what(), wxConvUTF8).c_str())); - } -} - - -// Include the generated tests -// -#include "regex.inc" - - -#endif // wxHAS_REGEX_ADVANCED diff --git a/tests/regex/regextest.cpp b/tests/regex/regextest.cpp new file mode 100644 index 0000000000..261435e8ed --- /dev/null +++ b/tests/regex/regextest.cpp @@ -0,0 +1,379 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/regex/regex.cpp +// Purpose: Test the built-in regex lib and wxRegEx +// Author: Mike Wetherell +// RCS-ID: $Id$ +// Copyright: (c) 2004 Mike Wetherell +// Licence: wxWidgets licence +/////////////////////////////////////////////////////////////////////////////// + +// +// Notes: +// +// To run just one section, say wx_1, do this: +// test regex.wx_1 +// +// To run all the regex tests: +// test regex +// +// Some tests must be skipped since they use features which we do not make +// available through wxRegEx. To see the list of tests that have been skipped +// turn on verbose logging, e.g.: +// test --verbose regex +// +// The tests here are for the builtin library, tests for wxRegEx in general +// should go in wxregex.cpp +// +// The tests are generated from Henry Spencer's reg.test, additional test +// can be added in wxreg.test. These test files are then turned into a C++ +// include file 'regex.inc' (included below) using a script 'regex.pl'. +// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +// for all others, include the necessary headers +#ifndef WX_PRECOMP + #include "wx/wx.h" +#endif + +#include "wx/regex.h" +#include "wx/cppunit.h" +#include + +using namespace std; +using namespace CppUnit; + +// many of the tests are specific to the builtin regex lib, so only attempts +// to do them when using the builtin regex lib. +// +#ifdef wxHAS_REGEX_ADVANCED + + +/////////////////////////////////////////////////////////////////////////////// +// The test case - an instance represents a single test + +class RegExTestCase : public TestCase +{ +public: + // constructor - create a single testcase + RegExTestCase( + const string& name, + const char *mode, + const char *id, + const char *flags, + const char *pattern, + const char *data, + const vector& expected); + +protected: + // run this testcase + void runTest(); + +private: + // workers + wxString Conv(const char *str); + void parseFlags(const wxString& flags); + void doTest(int flavor); + static wxString quote(const wxString& arg); + const wxChar *convError() const { return _T(""); } + + // assertions - adds some information about the test that failed + void fail(const wxString& msg) const; + void failIf(bool condition, const wxString& msg) const + { if (condition) fail(msg); } + + // mode, id, flags, pattern, test data, expected results... + int m_mode; + wxString m_id; + wxString m_flags; + wxString m_pattern; + wxString m_data; + wxArrayString m_expected; + + // the flag decoded + int m_compileFlags; + int m_matchFlags; + bool m_basic; + bool m_extended; + bool m_advanced; +}; + +// constructor - throws Exception on failure +// +RegExTestCase::RegExTestCase( + const string& name, + const char *mode, + const char *id, + const char *flags, + const char *pattern, + const char *data, + const vector& expected) + : + TestCase(name), + m_mode(mode[0]), + m_id(Conv(id)), + m_flags(Conv(flags)), + m_pattern(Conv(pattern)), + m_data(Conv(data)), + m_compileFlags(0), + m_matchFlags(0), + m_basic(false), + m_extended(false), + m_advanced(false) +{ + bool badconv = m_pattern == convError() || m_data == convError(); + vector::const_iterator it; + + for (it = expected.begin(); it != expected.end(); ++it) { + m_expected.push_back(Conv(*it)); + badconv = badconv || *m_expected.rbegin() == convError(); + } + + failIf(badconv, _T("cannot convert to default character encoding")); + + // the flags need further parsing... + parseFlags(m_flags); + +#ifndef wxHAS_REGEX_ADVANCED + failIf(!m_basic && !m_extended, _T("advanced regexs not available")); +#endif +} + +int wxWcscmp(const wchar_t* s1, const wchar_t* s2) +{ + size_t nLen1 = wxWcslen(s1); + size_t nLen2 = wxWcslen(s2); + + if (nLen1 != nLen2) + return nLen1 - nLen2; + + return wxMemcmp(s1, s2, nLen1); +} + +// convert a string from UTF8 to the internal encoding +// +wxString RegExTestCase::Conv(const char *str) +{ + const wxWCharBuffer wstr = wxConvUTF8.cMB2WC(str); + const wxWC2WXbuf buf = wxConvCurrent->cWC2WX(wstr); + + if (!buf || wxWcscmp(wxConvCurrent->cWX2WC(buf), wstr) != 0) + return convError(); + else + return buf; +} + +// Parse flags +// +void RegExTestCase::parseFlags(const wxString& flags) +{ + for (const wxChar *p = flags; *p; p++) { + switch (*p) { + // noop + case '-': break; + + // we don't fully support these flags, but they don't stop us + // checking for success of failure of the match, so treat as noop + case 'A': case 'B': case 'E': case 'H': + case 'I': case 'L': case 'M': case 'N': + case 'P': case 'Q': case 'R': case 'S': + case 'T': case 'U': case '%': + break; + + // match options + case '^': m_matchFlags |= wxRE_NOTBOL; break; + case '$': m_matchFlags |= wxRE_NOTEOL; break; +#if wxUSE_UNICODE + case '*': break; +#endif + // compile options + case '&': m_advanced = m_basic = true; break; + case 'b': m_basic = true; break; + case 'e': m_extended = true; break; + case 'i': m_compileFlags |= wxRE_ICASE; break; + case 'o': m_compileFlags |= wxRE_NOSUB; break; + case 'n': m_compileFlags |= wxRE_NEWLINE; break; + case 't': if (strchr("ep", m_mode)) break; // else fall through... + + // anything else we must skip the test + default: + fail(wxString::Format( + _T("requires unsupported flag '%c'"), *p)); + } + } +} + +// Try test for all flavours of expression specified +// +void RegExTestCase::runTest() +{ + if (m_basic) + doTest(wxRE_BASIC); + if (m_extended) + doTest(wxRE_EXTENDED); +#ifdef wxHAS_REGEX_ADVANCED + if (m_advanced || (!m_basic && !m_extended)) + doTest(wxRE_ADVANCED); +#endif +} + +// Try the test for a single flavour of expression +// +void RegExTestCase::doTest(int flavor) +{ + wxRegEx re(m_pattern, m_compileFlags | flavor); + + // 'e' - test that the pattern fails to compile + if (m_mode == 'e') { + failIf(re.IsValid(), _T("compile succeeded (should fail)")); + return; + } + failIf(!re.IsValid(), _T("compile failed")); + + bool matches = re.Matches(m_data, m_matchFlags); + + // 'f' or 'p' - test that the pattern does not match + if (m_mode == 'f' || m_mode == 'p') { + failIf(matches, _T("match succeeded (should fail)")); + return; + } + + // otherwise 'm' or 'i' - test the pattern does match + failIf(!matches, _T("match failed")); + + if (m_compileFlags & wxRE_NOSUB) + return; + + // check wxRegEx has correctly counted the number of subexpressions + failIf(m_expected.size() != re.GetMatchCount(), + wxString::Format(_T("GetMatchCount() == %d, expected %d"), + re.GetMatchCount(), m_expected.size())); + + wxString result; + size_t start, len; + + for (size_t i = 0; i < m_expected.size(); i++) { + failIf(!re.GetMatch(&start, &len, i), wxString::Format( + _T("wxRegEx::GetMatch failed for match %d"), i)); + + // m - check the match returns the strings given + if (m_mode == 'm') + if (start < INT_MAX) + result = m_data.substr(start, len); + else + result = _T(""); + + // i - check the match returns the offsets given + else if (m_mode == 'i') + if (start < INT_MAX) + result = wxString::Format(_T("%d %d"), start, start + len - 1); + else + result = _T("-1 -1"); + + failIf(result != m_expected[i], wxString::Format( + _T("match(%d) == %s, expected == %s"), i, + quote(result).c_str(), quote(m_expected[i]).c_str())); + } +} + +// assertion - adds some information about the test that failed +// +void RegExTestCase::fail(const wxString& msg) const +{ + wxString str; + wxArrayString::const_iterator it; + + str << (wxChar)m_mode << _T(" ") << m_id << _T(" ") << m_flags << _T(" ") + << quote(m_pattern) << _T(" ") << quote(m_data); + + for (it = m_expected.begin(); it != m_expected.end(); ++it) + str << _T(" ") << quote(*it); + + if (str.length() > 77) + str = str.substr(0, 74) + _T("..."); + + str << _T("\n ") << msg; + + // no lossy convs so using utf8 + CPPUNIT_FAIL(string(str.mb_str(wxConvUTF8))); +} + +// quote a string so that it can be displayed (static) +// +wxString RegExTestCase::quote(const wxString& arg) +{ + const wxChar *needEscape = _T("\a\b\t\n\v\f\r\"\\"); + const wxChar *escapes = _T("abtnvfr\"\\"); + wxString str; + + for (size_t i = 0; i < arg.length(); i++) { + wxUChar ch = arg[i]; + const wxChar *p = wxStrchr(needEscape, ch); + + if (p) + str += wxString::Format(_T("\\%c"), escapes[p - needEscape]); + else if (wxIscntrl(ch)) + str += wxString::Format(_T("\\%03o"), ch); + else + str += ch; + } + + return str.length() == arg.length() && str.find(' ') == wxString::npos ? + str : _T("\"") + str + _T("\""); +} + + +/////////////////////////////////////////////////////////////////////////////// +// Test suite + +class RegExTestSuite : public TestSuite +{ +public: + RegExTestSuite(string name) : TestSuite(name) { } + void add(const char *mode, const char *id, const char *flags, + const char *pattern, const char *data, const char *expected, ...); +}; + +// Add a testcase to the suite +// +void RegExTestSuite::add( + const char *mode, + const char *id, + const char *flags, + const char *pattern, + const char *data, + const char *expected, ...) +{ + string name = getName() + "." + id; + + vector expected_results; + va_list ap; + + for (va_start(ap, expected); expected; expected = va_arg(ap, const char *)) + expected_results.push_back(expected); + + va_end(ap); + + try { + addTest(new RegExTestCase( + name, mode, id, flags, pattern, data, expected_results)); + } + catch (Exception& e) { + wxLogInfo(wxString::Format(_T("skipping: %s\n %s\n"), + wxString(name.c_str(), wxConvUTF8).c_str(), + wxString(e.what(), wxConvUTF8).c_str())); + } +} + + +// Include the generated tests +// +#include "regex.inc" + + +#endif // wxHAS_REGEX_ADVANCED diff --git a/tests/regex/wxregex.cpp b/tests/regex/wxregex.cpp deleted file mode 100644 index fd8f19251f..0000000000 --- a/tests/regex/wxregex.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// Name: tests/regex/wxregex.cpp -// Purpose: Test wxRegEx -// Author: Vadim Zeitlin, Mike Wetherell -// RCS-ID: $Id$ -// Copyright: Vadim Zeitlin, Mike Wetherell -// Licence: wxWidgets licence -/////////////////////////////////////////////////////////////////////////////// - -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ -# pragma hdrstop -#endif - -#ifndef WX_PRECOMP -# include "wx/wx.h" -#endif - -#if wxUSE_REGEX - -#include "wx/regex.h" -#include "wx/cppunit.h" -#include "wx/tokenzr.h" -#include - -using namespace std; -using namespace CppUnit; - - -/////////////////////////////////////////////////////////////////////////////// -// Compile Test - -class RegExCompileTestCase : public TestCase -{ -public: - RegExCompileTestCase(const char *name, const wxString& pattern, - bool correct, int flags) - : TestCase(name), - m_pattern(pattern), - m_correct(correct), - m_flags(flags) - { } - -protected: - void runTest(); - -private: - wxString m_pattern; - bool m_correct; - int m_flags; -}; - -void RegExCompileTestCase::runTest() -{ - wxRegEx re; - bool ok = re.Compile(m_pattern, m_flags); - - if (m_correct) - CPPUNIT_ASSERT_MESSAGE("compile failed", ok); - else - CPPUNIT_ASSERT_MESSAGE("compile succeeded (should fail)", !ok); -} - - -/////////////////////////////////////////////////////////////////////////////// -// Match Test - -class RegExMatchTestCase : public TestCase -{ -public: - RegExMatchTestCase(const char *name, const wxString& pattern, - const wxString& text, const char *expected, - int flags) - : TestCase(name), - m_pattern(pattern), - m_text(text), - m_expected(expected), - m_flags(flags) - { } - -protected: - void runTest(); - -private: - wxString m_pattern; - wxString m_text; - const char *m_expected; - int m_flags; -}; - -void RegExMatchTestCase::runTest() -{ - int compileFlags = m_flags & ~(wxRE_NOTBOL | wxRE_NOTEOL); - int matchFlags = m_flags & (wxRE_NOTBOL | wxRE_NOTEOL); - - wxRegEx re(m_pattern, compileFlags); - CPPUNIT_ASSERT_MESSAGE("compile failed", re.IsValid()); - - bool ok = re.Matches(m_text, matchFlags); - - if (m_expected) { - CPPUNIT_ASSERT_MESSAGE("match failed", ok); - - wxStringTokenizer tkz(wxString(m_expected, *wxConvCurrent), - _T("\t"), wxTOKEN_RET_EMPTY); - size_t i; - - for (i = 0; i < re.GetMatchCount() && tkz.HasMoreTokens(); i++) { - wxString expected = tkz.GetNextToken(); - wxString result = re.GetMatch(m_text, i); - - wxString msgstr; - msgstr.Printf(_T("\\%d == '%s' (expected '%s')"), - (int)i, result.c_str(), expected.c_str()); - const char *msg = msgstr.mb_str(); - - CPPUNIT_ASSERT_MESSAGE(msg, result == expected); - } - - if ((m_flags & wxRE_NOSUB) == 0) - CPPUNIT_ASSERT(re.GetMatchCount() == i); - } - else { - CPPUNIT_ASSERT_MESSAGE("match succeeded (should fail)", !ok); - } -} - - -/////////////////////////////////////////////////////////////////////////////// -// Replacement Test - -class RegExReplaceTestCase : public TestCase -{ -public: - RegExReplaceTestCase(const char *name, const wxString& pattern, - const wxString& text, const wxString& repl, - const wxString& expected, size_t count, int flags) - : TestCase(name), - m_pattern(pattern), - m_text(text), - m_repl(repl), - m_expected(expected), - m_count(count), - m_flags(flags) - { } - -protected: - void runTest(); - -private: - wxString m_pattern; - wxString m_text; - wxString m_repl; - wxString m_expected; - size_t m_count; - int m_flags; -}; - -void RegExReplaceTestCase::runTest() -{ - wxRegEx re(m_pattern, m_flags); - - wxString text(m_text); - size_t nRepl = re.Replace(&text, m_repl); - - wxString msgstr; - msgstr.Printf(_T("returns '%s' (expected '%s')"), text.c_str(), m_expected.c_str()); - const char *msg = msgstr.mb_str(); - CPPUNIT_ASSERT_MESSAGE(msg, text == m_expected); - - msgstr.Printf(_T("matches %d times (expected %d)"), nRepl, m_count); - msg = msgstr.mb_str(); - CPPUNIT_ASSERT_MESSAGE(msg, nRepl == m_count); -} - - -/////////////////////////////////////////////////////////////////////////////// -// The suite - -class wxRegExTestSuite : public TestSuite -{ -public: - wxRegExTestSuite() : TestSuite("wxRegExTestSuite") { } - static Test *suite(); - -private: - void add(const char *pattern, bool correct, int flags = wxRE_DEFAULT); - void add(const char *pattern, const char *text, - const char *expected = NULL, int flags = wxRE_DEFAULT); - void add(const char *pattern, const char *text, const char *replacement, - const char *expected, size_t count, int flags = wxRE_DEFAULT); - - static wxString FlagStr(int flags); - static wxString Conv(const char *str) { return wxString(str, *wxConvCurrent); } -}; - -// Build the suite (static) -// -Test *wxRegExTestSuite::suite() -{ - wxRegExTestSuite *suite = new wxRegExTestSuite; - - // Compile tests - // pattern, expected result - suite->add("foo", true); - suite->add("foo(", false); - suite->add("foo(bar", false); - suite->add("foo(bar)", true); - suite->add("foo[", false); - suite->add("foo[bar", false); - suite->add("foo[bar]", true); - suite->add("foo{1", false); - suite->add("foo{1}", true); - suite->add("foo{1,2}", true); - suite->add("foo*", true); - suite->add("foo+", true); - suite->add("foo?", true); - - // Match tests - // pattern, text, expected results (match, followed by submatches - // tab separated, or NULL for no match expected) - suite->add("foo", "bar"); - suite->add("foo", "foobar", "foo"); - suite->add("^foo", "foobar", "foo"); - suite->add("^foo", "barfoo"); - suite->add("bar$", "barbar", "bar"); - suite->add("bar$", "barbar "); - suite->add("OoBa", "FoObAr", "oObA", wxRE_ICASE); - suite->add("^[A-Z].*$", "AA\nbb\nCC", "AA\nbb\nCC"); - suite->add("^[A-Z].*$", "AA\nbb\nCC", "AA", wxRE_NEWLINE); - suite->add("^[a-z].*$", "AA\nbb\nCC", "bb", wxRE_NEWLINE); - suite->add("^[A-Z].*$", "AA\nbb\nCC", "CC", wxRE_NEWLINE | wxRE_NOTBOL); - suite->add("^[A-Z].*$", "AA\nbb\nCC", NULL, wxRE_NEWLINE | wxRE_NOTBOL | wxRE_NOTEOL); - suite->add("([[:alpha:]]+) ([[:alpha:]]+) ([[:digit:]]+).* ([[:digit:]]+)$", - "Fri Jul 13 18:37:52 CEST 2001", - "Fri Jul 13 18:37:52 CEST 2001\tFri\tJul\t13\t2001"); - - // Replace tests - // pattern, text, replacement, expected result and number of matches - const char *patn = "([a-z]+)[^0-9]*([0-9]+)"; - suite->add(patn, "foo123", "bar", "bar", 1); - suite->add(patn, "foo123", "\\2\\1", "123foo", 1); - suite->add(patn, "foo_123", "\\2\\1", "123foo", 1); - suite->add(patn, "123foo", "bar", "123foo", 0); - suite->add(patn, "123foo456foo", "&&", "123foo456foo456foo", 1); - suite->add(patn, "123foo456foo", "\\0\\0", "123foo456foo456foo", 1); - suite->add(patn, "foo123foo123", "bar", "barbar", 2); - suite->add(patn, "foo123_foo456_foo789", "bar", "bar_bar_bar", 3); - - return suite; -} - -// Add a compile test -// -void wxRegExTestSuite::add( - const char *pattern, - bool correct, - int flags /*=wxRE_DEFAULT*/) -{ - addTest(new RegExCompileTestCase( - (_T("/") + Conv(pattern) + _T("/") + FlagStr(flags)).mb_str(), - Conv(pattern), correct, flags)); -} - -// Add a match test -// -void wxRegExTestSuite::add( - const char *pattern, - const char *text, - const char *expected /*=NULL*/, - int flags /*=wxRE_DEFAULT*/) -{ - wxString name; - - name << _T("'") << Conv(text) << _T("' =~ /") << Conv(pattern) << _T("/") - << FlagStr(flags); - name.Replace(_T("\n"), _T("\\n")); - - addTest(new RegExMatchTestCase(name.mb_str(), Conv(pattern), - Conv(text), expected, flags)); -} - -// Add a replace test -// -void wxRegExTestSuite::add( - const char *pattern, - const char *text, - const char *replacement, - const char *expected, - size_t count, - int flags /*=wxRE_DEFAULT*/) -{ - wxString name; - - name << _T("'") << Conv(text) << _T("' =~ s/") << Conv(pattern) << _T("/") - << Conv(replacement) << _T("/g") << FlagStr(flags); - name.Replace(_T("\n"), _T("\\n")); - - addTest(new RegExReplaceTestCase( - name.mb_str(), Conv(pattern), Conv(text), - Conv(replacement), Conv(expected), count, flags)); -} - -// Display string for the flags -// -wxString wxRegExTestSuite::FlagStr(int flags) -{ - wxString str; - - if (!flags) - return str; - - for (int i = 0; (unsigned)flags >> i; i++) { - switch (flags & (1 << i)) { - case 0: break; -#ifdef wxHAS_REGEX_ADVANCED - case wxRE_ADVANCED: str += _T(" | wxRE_ADVANCED"); break; -#endif - case wxRE_BASIC: str += _T(" | wxRE_BASIC"); break; - case wxRE_ICASE: str += _T(" | wxRE_ICASE"); break; - case wxRE_NOSUB: str += _T(" | wxRE_NOSUB"); break; - case wxRE_NEWLINE: str += _T(" | wxRE_NEWLINE"); break; - case wxRE_NOTBOL: str += _T(" | wxRE_NOTBOL"); break; - case wxRE_NOTEOL: str += _T(" | wxRE_NOTEOL"); break; - default: wxFAIL; break; - } - } - - return _T(" (") + str.Mid(3) + _T(")"); -}; - -// register in the unnamed registry so that these tests are run by default -CPPUNIT_TEST_SUITE_REGISTRATION(wxRegExTestSuite); - -// also include in it's own registry so that these tests can be run alone -CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(wxRegExTestSuite, "wxRegExTestSuite"); - - -#endif // wxUSE_REGEX diff --git a/tests/regex/wxregextest.cpp b/tests/regex/wxregextest.cpp new file mode 100644 index 0000000000..fd8f19251f --- /dev/null +++ b/tests/regex/wxregextest.cpp @@ -0,0 +1,340 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/regex/wxregex.cpp +// Purpose: Test wxRegEx +// Author: Vadim Zeitlin, Mike Wetherell +// RCS-ID: $Id$ +// Copyright: Vadim Zeitlin, Mike Wetherell +// Licence: wxWidgets licence +/////////////////////////////////////////////////////////////////////////////// + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +# pragma hdrstop +#endif + +#ifndef WX_PRECOMP +# include "wx/wx.h" +#endif + +#if wxUSE_REGEX + +#include "wx/regex.h" +#include "wx/cppunit.h" +#include "wx/tokenzr.h" +#include + +using namespace std; +using namespace CppUnit; + + +/////////////////////////////////////////////////////////////////////////////// +// Compile Test + +class RegExCompileTestCase : public TestCase +{ +public: + RegExCompileTestCase(const char *name, const wxString& pattern, + bool correct, int flags) + : TestCase(name), + m_pattern(pattern), + m_correct(correct), + m_flags(flags) + { } + +protected: + void runTest(); + +private: + wxString m_pattern; + bool m_correct; + int m_flags; +}; + +void RegExCompileTestCase::runTest() +{ + wxRegEx re; + bool ok = re.Compile(m_pattern, m_flags); + + if (m_correct) + CPPUNIT_ASSERT_MESSAGE("compile failed", ok); + else + CPPUNIT_ASSERT_MESSAGE("compile succeeded (should fail)", !ok); +} + + +/////////////////////////////////////////////////////////////////////////////// +// Match Test + +class RegExMatchTestCase : public TestCase +{ +public: + RegExMatchTestCase(const char *name, const wxString& pattern, + const wxString& text, const char *expected, + int flags) + : TestCase(name), + m_pattern(pattern), + m_text(text), + m_expected(expected), + m_flags(flags) + { } + +protected: + void runTest(); + +private: + wxString m_pattern; + wxString m_text; + const char *m_expected; + int m_flags; +}; + +void RegExMatchTestCase::runTest() +{ + int compileFlags = m_flags & ~(wxRE_NOTBOL | wxRE_NOTEOL); + int matchFlags = m_flags & (wxRE_NOTBOL | wxRE_NOTEOL); + + wxRegEx re(m_pattern, compileFlags); + CPPUNIT_ASSERT_MESSAGE("compile failed", re.IsValid()); + + bool ok = re.Matches(m_text, matchFlags); + + if (m_expected) { + CPPUNIT_ASSERT_MESSAGE("match failed", ok); + + wxStringTokenizer tkz(wxString(m_expected, *wxConvCurrent), + _T("\t"), wxTOKEN_RET_EMPTY); + size_t i; + + for (i = 0; i < re.GetMatchCount() && tkz.HasMoreTokens(); i++) { + wxString expected = tkz.GetNextToken(); + wxString result = re.GetMatch(m_text, i); + + wxString msgstr; + msgstr.Printf(_T("\\%d == '%s' (expected '%s')"), + (int)i, result.c_str(), expected.c_str()); + const char *msg = msgstr.mb_str(); + + CPPUNIT_ASSERT_MESSAGE(msg, result == expected); + } + + if ((m_flags & wxRE_NOSUB) == 0) + CPPUNIT_ASSERT(re.GetMatchCount() == i); + } + else { + CPPUNIT_ASSERT_MESSAGE("match succeeded (should fail)", !ok); + } +} + + +/////////////////////////////////////////////////////////////////////////////// +// Replacement Test + +class RegExReplaceTestCase : public TestCase +{ +public: + RegExReplaceTestCase(const char *name, const wxString& pattern, + const wxString& text, const wxString& repl, + const wxString& expected, size_t count, int flags) + : TestCase(name), + m_pattern(pattern), + m_text(text), + m_repl(repl), + m_expected(expected), + m_count(count), + m_flags(flags) + { } + +protected: + void runTest(); + +private: + wxString m_pattern; + wxString m_text; + wxString m_repl; + wxString m_expected; + size_t m_count; + int m_flags; +}; + +void RegExReplaceTestCase::runTest() +{ + wxRegEx re(m_pattern, m_flags); + + wxString text(m_text); + size_t nRepl = re.Replace(&text, m_repl); + + wxString msgstr; + msgstr.Printf(_T("returns '%s' (expected '%s')"), text.c_str(), m_expected.c_str()); + const char *msg = msgstr.mb_str(); + CPPUNIT_ASSERT_MESSAGE(msg, text == m_expected); + + msgstr.Printf(_T("matches %d times (expected %d)"), nRepl, m_count); + msg = msgstr.mb_str(); + CPPUNIT_ASSERT_MESSAGE(msg, nRepl == m_count); +} + + +/////////////////////////////////////////////////////////////////////////////// +// The suite + +class wxRegExTestSuite : public TestSuite +{ +public: + wxRegExTestSuite() : TestSuite("wxRegExTestSuite") { } + static Test *suite(); + +private: + void add(const char *pattern, bool correct, int flags = wxRE_DEFAULT); + void add(const char *pattern, const char *text, + const char *expected = NULL, int flags = wxRE_DEFAULT); + void add(const char *pattern, const char *text, const char *replacement, + const char *expected, size_t count, int flags = wxRE_DEFAULT); + + static wxString FlagStr(int flags); + static wxString Conv(const char *str) { return wxString(str, *wxConvCurrent); } +}; + +// Build the suite (static) +// +Test *wxRegExTestSuite::suite() +{ + wxRegExTestSuite *suite = new wxRegExTestSuite; + + // Compile tests + // pattern, expected result + suite->add("foo", true); + suite->add("foo(", false); + suite->add("foo(bar", false); + suite->add("foo(bar)", true); + suite->add("foo[", false); + suite->add("foo[bar", false); + suite->add("foo[bar]", true); + suite->add("foo{1", false); + suite->add("foo{1}", true); + suite->add("foo{1,2}", true); + suite->add("foo*", true); + suite->add("foo+", true); + suite->add("foo?", true); + + // Match tests + // pattern, text, expected results (match, followed by submatches + // tab separated, or NULL for no match expected) + suite->add("foo", "bar"); + suite->add("foo", "foobar", "foo"); + suite->add("^foo", "foobar", "foo"); + suite->add("^foo", "barfoo"); + suite->add("bar$", "barbar", "bar"); + suite->add("bar$", "barbar "); + suite->add("OoBa", "FoObAr", "oObA", wxRE_ICASE); + suite->add("^[A-Z].*$", "AA\nbb\nCC", "AA\nbb\nCC"); + suite->add("^[A-Z].*$", "AA\nbb\nCC", "AA", wxRE_NEWLINE); + suite->add("^[a-z].*$", "AA\nbb\nCC", "bb", wxRE_NEWLINE); + suite->add("^[A-Z].*$", "AA\nbb\nCC", "CC", wxRE_NEWLINE | wxRE_NOTBOL); + suite->add("^[A-Z].*$", "AA\nbb\nCC", NULL, wxRE_NEWLINE | wxRE_NOTBOL | wxRE_NOTEOL); + suite->add("([[:alpha:]]+) ([[:alpha:]]+) ([[:digit:]]+).* ([[:digit:]]+)$", + "Fri Jul 13 18:37:52 CEST 2001", + "Fri Jul 13 18:37:52 CEST 2001\tFri\tJul\t13\t2001"); + + // Replace tests + // pattern, text, replacement, expected result and number of matches + const char *patn = "([a-z]+)[^0-9]*([0-9]+)"; + suite->add(patn, "foo123", "bar", "bar", 1); + suite->add(patn, "foo123", "\\2\\1", "123foo", 1); + suite->add(patn, "foo_123", "\\2\\1", "123foo", 1); + suite->add(patn, "123foo", "bar", "123foo", 0); + suite->add(patn, "123foo456foo", "&&", "123foo456foo456foo", 1); + suite->add(patn, "123foo456foo", "\\0\\0", "123foo456foo456foo", 1); + suite->add(patn, "foo123foo123", "bar", "barbar", 2); + suite->add(patn, "foo123_foo456_foo789", "bar", "bar_bar_bar", 3); + + return suite; +} + +// Add a compile test +// +void wxRegExTestSuite::add( + const char *pattern, + bool correct, + int flags /*=wxRE_DEFAULT*/) +{ + addTest(new RegExCompileTestCase( + (_T("/") + Conv(pattern) + _T("/") + FlagStr(flags)).mb_str(), + Conv(pattern), correct, flags)); +} + +// Add a match test +// +void wxRegExTestSuite::add( + const char *pattern, + const char *text, + const char *expected /*=NULL*/, + int flags /*=wxRE_DEFAULT*/) +{ + wxString name; + + name << _T("'") << Conv(text) << _T("' =~ /") << Conv(pattern) << _T("/") + << FlagStr(flags); + name.Replace(_T("\n"), _T("\\n")); + + addTest(new RegExMatchTestCase(name.mb_str(), Conv(pattern), + Conv(text), expected, flags)); +} + +// Add a replace test +// +void wxRegExTestSuite::add( + const char *pattern, + const char *text, + const char *replacement, + const char *expected, + size_t count, + int flags /*=wxRE_DEFAULT*/) +{ + wxString name; + + name << _T("'") << Conv(text) << _T("' =~ s/") << Conv(pattern) << _T("/") + << Conv(replacement) << _T("/g") << FlagStr(flags); + name.Replace(_T("\n"), _T("\\n")); + + addTest(new RegExReplaceTestCase( + name.mb_str(), Conv(pattern), Conv(text), + Conv(replacement), Conv(expected), count, flags)); +} + +// Display string for the flags +// +wxString wxRegExTestSuite::FlagStr(int flags) +{ + wxString str; + + if (!flags) + return str; + + for (int i = 0; (unsigned)flags >> i; i++) { + switch (flags & (1 << i)) { + case 0: break; +#ifdef wxHAS_REGEX_ADVANCED + case wxRE_ADVANCED: str += _T(" | wxRE_ADVANCED"); break; +#endif + case wxRE_BASIC: str += _T(" | wxRE_BASIC"); break; + case wxRE_ICASE: str += _T(" | wxRE_ICASE"); break; + case wxRE_NOSUB: str += _T(" | wxRE_NOSUB"); break; + case wxRE_NEWLINE: str += _T(" | wxRE_NEWLINE"); break; + case wxRE_NOTBOL: str += _T(" | wxRE_NOTBOL"); break; + case wxRE_NOTEOL: str += _T(" | wxRE_NOTEOL"); break; + default: wxFAIL; break; + } + } + + return _T(" (") + str.Mid(3) + _T(")"); +}; + +// register in the unnamed registry so that these tests are run by default +CPPUNIT_TEST_SUITE_REGISTRATION(wxRegExTestSuite); + +// also include in it's own registry so that these tests can be run alone +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(wxRegExTestSuite, "wxRegExTestSuite"); + + +#endif // wxUSE_REGEX diff --git a/tests/test.bkl b/tests/test.bkl index 0323cdd6e7..64bfcc7c67 100644 --- a/tests/test.bkl +++ b/tests/test.bkl @@ -10,17 +10,17 @@ test.cpp arrays/arrays.cpp - datetime/datetime.cpp - fileconf/fileconf.cpp - filename/filename.cpp - filesys/filesys.cpp - fontmap/fontmap.cpp - formatconverter/formatconverter.cpp + datetime/datetimetest.cpp + fileconf/fileconftest.cpp + filename/filenametest.cpp + filesys/filesystest.cpp + fontmap/fontmaptest.cpp + formatconverter/formatconvertertest.cpp hashes/hashes.cpp - longlong/longlong.cpp - mbconv/main.cpp - regex/regex.cpp - regex/wxregex.cpp + longlong/longlongtest.cpp + mbconv/mbconvtest.cpp + regex/regextest.cpp + regex/wxregextest.cpp strings/strings.cpp strings/stdstrings.cpp strings/unicode.cpp