hrev47931 adds 2 changesets to branch 'master' old head: 6e80c1ca11a81c8187f4f3edb4adbb62d570fc9d new head: f188c1defa3ffef28c2a76b1b21fa7dc017f3e5b overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=f188c1d+%5E6e80c1c ---------------------------------------------------------------------------- dd21b46: Add tests for BDateFormat. f188c1d: BDateFormat: improve API * Use a reference rather than a pointer for the output string, removing the need for NULL checks (which were missing, anyway) * Adjust callers to that change * Add new Format variant taking a BDate argument [ Adrien Destugues <pulkomandy@xxxxxxxxx> ] ---------------------------------------------------------------------------- 11 files changed, 208 insertions(+), 29 deletions(-) headers/os/locale/DateFormat.h | 18 ++-- src/kits/locale/DateFormat.cpp | 76 ++++++++++++---- src/kits/support/DateTime.cpp | 1 - src/kits/tracker/WidgetAttributeText.cpp | 2 +- src/preferences/locale/FormatSettingsView.cpp | 8 +- src/preferences/time/DateTimeEdit.cpp | 2 +- src/preferences/time/TimeZoneListView.cpp | 2 +- src/tests/kits/locale/DateFormatTest.cpp | 100 ++++++++++++++++++++++ src/tests/kits/locale/DateFormatTest.h | 25 ++++++ src/tests/kits/locale/Jamfile | 1 + src/tests/kits/locale/LocaleKitTestAddon.cpp | 2 + ############################################################################ Commit: dd21b4666eae8c41fa054b0aedce6f79a899e2d4 URL: http://cgit.haiku-os.org/haiku/commit/?id=dd21b46 Author: Adrien Destugues <pulkomandy@xxxxxxxxx> Date: Tue Sep 30 07:37:03 2014 UTC Add tests for BDateFormat. ---------------------------------------------------------------------------- diff --git a/src/tests/kits/locale/DateFormatTest.cpp b/src/tests/kits/locale/DateFormatTest.cpp new file mode 100644 index 0000000..2cc1d41 --- /dev/null +++ b/src/tests/kits/locale/DateFormatTest.cpp @@ -0,0 +1,100 @@ +/* + * Copyright 2014 Haiku, Inc. + * Distributed under the terms of the MIT License. + */ + + +#include "DateFormatTest.h" + +#include <DateFormat.h> +#include <FormattingConventions.h> +#include <Language.h> + +#include <cppunit/TestCaller.h> +#include <cppunit/TestSuite.h> + + +DateFormatTest::DateFormatTest() +{ +} + + +DateFormatTest::~DateFormatTest() +{ +} + + +void +DateFormatTest::TestFormat() +{ + struct Value { + char* language; + char* convention; + time_t time; + char* shortDate; + char* longDate; + }; + + static const Value values[] = { + {"en", "en_US", 12345, "1/1/70", "January 1, 1970"}, + {"fr", "fr_FR", 12345, "01/01/70", "1 janvier 1970"}, + {"fr", "fr_FR", 12345678, "23/05/70", "23 mai 1970"}, + {NULL} + }; + + BString output; + status_t result; + + for (int i = 0; values[i].language != NULL; i++) { + NextSubTest(); + + BLanguage language(values[i].language); + BFormattingConventions formatting(values[i].convention); + BDateFormat format(&language, &formatting); + + result = format.Format(output, values[i].time, B_SHORT_DATE_FORMAT); + CPPUNIT_ASSERT_EQUAL(B_OK, result); + CPPUNIT_ASSERT_EQUAL(BString(values[i].shortDate), output); + + result = format.Format(output, values[i].time, B_LONG_DATE_FORMAT); + CPPUNIT_ASSERT_EQUAL(B_OK, result); + CPPUNIT_ASSERT_EQUAL(BString(values[i].longDate), output); + } +} + + +void +DateFormatTest::TestFormatDate() +{ + BLanguage language("en"); + BFormattingConventions formatting("en_US"); + BDateFormat format(&language, &formatting); + + BString output; + status_t result; + + BDate date(2014, 9, 29); + + result = format.Format(output, date, B_LONG_DATE_FORMAT); + CPPUNIT_ASSERT_EQUAL(B_OK, result); + CPPUNIT_ASSERT_EQUAL(BString("September 29, 2014"), output); + + // Test an invalid date - must return B_BAD_DATA + date.SetDate(2014, 29, 29); + result = format.Format(output, date, B_LONG_DATE_FORMAT); + CPPUNIT_ASSERT_EQUAL(B_BAD_DATA, result); +} + + +/*static*/ void +DateFormatTest::AddTests(BTestSuite& parent) +{ + CppUnit::TestSuite& suite = *new CppUnit::TestSuite("DateFormatTest"); + + suite.addTest(new CppUnit::TestCaller<DateFormatTest>( + "DateFormatTest::TestFormat", &DateFormatTest::TestFormat)); + suite.addTest(new CppUnit::TestCaller<DateFormatTest>( + "DateFormatTest::TestFormatDate", &DateFormatTest::TestFormatDate)); + + parent.addTest("DateFormatTest", &suite); +} diff --git a/src/tests/kits/locale/DateFormatTest.h b/src/tests/kits/locale/DateFormatTest.h new file mode 100644 index 0000000..d3a34c3 --- /dev/null +++ b/src/tests/kits/locale/DateFormatTest.h @@ -0,0 +1,25 @@ +/* + * Copyright 2014 Haiku, Inc. + * Distributed under the terms of the MIT License. + */ +#ifndef DATE_FORMAT_TEST_H +#define DATE_FORMAT_TEST_H + + +#include <TestCase.h> +#include <TestSuite.h> + + +class DateFormatTest: public BTestCase { +public: + DateFormatTest(); + virtual ~DateFormatTest(); + + void TestFormat(); + void TestFormatDate(); + + static void AddTests(BTestSuite& suite); +}; + + +#endif diff --git a/src/tests/kits/locale/Jamfile b/src/tests/kits/locale/Jamfile index 8caf5c0..5e9af75 100644 --- a/src/tests/kits/locale/Jamfile +++ b/src/tests/kits/locale/Jamfile @@ -50,6 +50,7 @@ UnitTestLib localekittest.so : LocaleKitTestAddon.cpp CollatorTest.cpp + DateFormatTest.cpp LanguageTest.cpp UnicodeCharTest.cpp diff --git a/src/tests/kits/locale/LocaleKitTestAddon.cpp b/src/tests/kits/locale/LocaleKitTestAddon.cpp index 0877206..93eb87f 100644 --- a/src/tests/kits/locale/LocaleKitTestAddon.cpp +++ b/src/tests/kits/locale/LocaleKitTestAddon.cpp @@ -8,6 +8,7 @@ #include <TestSuiteAddon.h> #include "CollatorTest.h" +#include "DateFormatTest.h" #include "LanguageTest.h" #include "UnicodeCharTest.h" @@ -18,6 +19,7 @@ getTestSuite() BTestSuite* suite = new BTestSuite("LocaleKit"); CollatorTest::AddTests(*suite); + DateFormatTest::AddTests(*suite); LanguageTest::AddTests(*suite); UnicodeCharTest::AddTests(*suite); ############################################################################ Revision: hrev47931 Commit: f188c1defa3ffef28c2a76b1b21fa7dc017f3e5b URL: http://cgit.haiku-os.org/haiku/commit/?id=f188c1d Author: Adrien Destugues <pulkomandy@xxxxxxxxx> Date: Tue Sep 30 07:39:18 2014 UTC BDateFormat: improve API * Use a reference rather than a pointer for the output string, removing the need for NULL checks (which were missing, anyway) * Adjust callers to that change * Add new Format variant taking a BDate argument ---------------------------------------------------------------------------- diff --git a/headers/os/locale/DateFormat.h b/headers/os/locale/DateFormat.h index 31dbbc2..ec11d7f 100644 --- a/headers/os/locale/DateFormat.h +++ b/headers/os/locale/DateFormat.h @@ -6,6 +6,7 @@ #define _B_DATE_FORMAT_H_ +#include <DateTime.h> #include <DateTimeFormat.h> #include <FormattingConventions.h> #include <Language.h> @@ -38,14 +39,19 @@ public: // formatting - ssize_t Format(char* string, size_t maxSize, - time_t time, BDateFormatStyle style) const; - status_t Format(BString* string, time_t time, - BDateFormatStyle style, + ssize_t Format(char* string, const size_t maxSize, + const time_t time, + const BDateFormatStyle style) const; + status_t Format(BString& string, const time_t time, + const BDateFormatStyle style, const BTimeZone* timeZone = NULL) const; - status_t Format(BString* string, + status_t Format(BString& string, const BDate& time, + const BDateFormatStyle style, + const BTimeZone* timeZone = NULL) const; + status_t Format(BString& string, int*& fieldPositions, int& fieldCount, - time_t time, BDateFormatStyle style) const; + const time_t time, + const BDateFormatStyle style) const; status_t GetFields(BDateElement*& fields, int& fieldCount, BDateFormatStyle style diff --git a/src/kits/locale/DateFormat.cpp b/src/kits/locale/DateFormat.cpp index 08a80c2..8521a42 100644 --- a/src/kits/locale/DateFormat.cpp +++ b/src/kits/locale/DateFormat.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2010, Haiku, Inc. All Rights Reserved. + * Copyright 2010-2014, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -24,7 +24,6 @@ #include <vector> -// default constructor BDateFormat::BDateFormat(const BLanguage* const language, const BFormattingConventions* const conventions) { @@ -39,13 +38,14 @@ BDateFormat::BDateFormat(const BLanguage* const language, BLocale::Default()->GetLanguage(&fLanguage); } -// copy constructor + BDateFormat::BDateFormat(const BDateFormat &other) : fConventions(other.fConventions), fLanguage(other.fLanguage) { } + /*static*/ const BDateFormat* BDateFormat::Default() { @@ -53,15 +53,14 @@ BDateFormat::Default() } -// destructor BDateFormat::~BDateFormat() { } -// Format + ssize_t -BDateFormat::Format(char* string, size_t maxSize, time_t time, - BDateFormatStyle style) const +BDateFormat::Format(char* string, const size_t maxSize, const time_t time, + const BDateFormatStyle style) const { BAutolock lock(fLock); if (!lock.IsLocked()) @@ -87,8 +86,8 @@ BDateFormat::Format(char* string, size_t maxSize, time_t time, status_t -BDateFormat::Format(BString *string, time_t time, BDateFormatStyle style, - const BTimeZone* timeZone) const +BDateFormat::Format(BString& string, const time_t time, + const BDateFormatStyle style, const BTimeZone* timeZone) const { BAutolock lock(fLock); if (!lock.IsLocked()) @@ -111,8 +110,55 @@ BDateFormat::Format(BString *string, time_t time, BDateFormatStyle style, UnicodeString icuString; dateFormatter->format((UDate)time * 1000, icuString); - string->Truncate(0); - BStringByteSink stringConverter(string); + string.Truncate(0); + BStringByteSink stringConverter(&string); + icuString.toUTF8(stringConverter); + + return B_OK; +} + + +status_t +BDateFormat::Format(BString& string, const BDate& time, + const BDateFormatStyle style, const BTimeZone* timeZone) const +{ + if (!time.IsValid()) + return B_BAD_DATA; + + BAutolock lock(fLock); + if (!lock.IsLocked()) + return B_ERROR; + + BString format; + fConventions.GetDateFormat(style, format); + ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format)); + if (dateFormatter.Get() == NULL) + return B_NO_MEMORY; + + UErrorCode err = U_ZERO_ERROR; + ObjectDeleter<Calendar> calendar(Calendar::createInstance(err)); + if (!U_SUCCESS(err)) + return B_NO_MEMORY; + + if (timeZone != NULL) { + ObjectDeleter<TimeZone> icuTimeZone( + TimeZone::createTimeZone(timeZone->ID().String())); + if (icuTimeZone.Get() == NULL) + return B_NO_MEMORY; + dateFormatter->setTimeZone(*icuTimeZone.Get()); + calendar->setTimeZone(*icuTimeZone.Get()); + } + + // Note ICU calendar uses months in range 0..11, while we use the more + // natural 1..12 in BDate. + calendar->set(time.Year(), time.Month() - 1, time.Day()); + + UnicodeString icuString; + FieldPosition p; + dateFormatter->format(*calendar.Get(), icuString, p); + + string.Truncate(0); + BStringByteSink stringConverter(&string); icuString.toUTF8(stringConverter); return B_OK; @@ -120,8 +166,8 @@ BDateFormat::Format(BString *string, time_t time, BDateFormatStyle style, status_t -BDateFormat::Format(BString* string, int*& fieldPositions, int& fieldCount, - time_t time, BDateFormatStyle style) const +BDateFormat::Format(BString& string, int*& fieldPositions, int& fieldCount, + const time_t time, const BDateFormatStyle style) const { BAutolock lock(fLock); if (!lock.IsLocked()) @@ -157,8 +203,8 @@ BDateFormat::Format(BString* string, int*& fieldPositions, int& fieldCount, for (int i = 0 ; i < fieldCount ; i++ ) fieldPositions[i] = fieldPosStorage[i]; - string->Truncate(0); - BStringByteSink stringConverter(string); + string.Truncate(0); + BStringByteSink stringConverter(&string); icuString.toUTF8(stringConverter); diff --git a/src/kits/support/DateTime.cpp b/src/kits/support/DateTime.cpp index 3d4a051..e07e437 100644 --- a/src/kits/support/DateTime.cpp +++ b/src/kits/support/DateTime.cpp @@ -202,7 +202,6 @@ BTime::SetTime(int32 hour, int32 minute, int32 second, int32 microsecond) } - /*! Adds \c hours to the current time. If the passed value is negative it will become earlier. Note: The time will wrap if it passes midnight. diff --git a/src/kits/tracker/WidgetAttributeText.cpp b/src/kits/tracker/WidgetAttributeText.cpp index 5daff1f..365fe88 100644 --- a/src/kits/tracker/WidgetAttributeText.cpp +++ b/src/kits/tracker/WidgetAttributeText.cpp @@ -214,7 +214,7 @@ TruncTimeBase(BString* outString, int64 value, const View* view, float width) } if (resultWidth > width - && BDateFormat::Default()->Format(&date, timeValue, + && BDateFormat::Default()->Format(date, timeValue, B_SHORT_DATE_FORMAT) == B_OK) { resultWidth = view->StringWidth(date.String(), date.Length()); } diff --git a/src/preferences/locale/FormatSettingsView.cpp b/src/preferences/locale/FormatSettingsView.cpp index 0b58029..d7fee35 100644 --- a/src/preferences/locale/FormatSettingsView.cpp +++ b/src/preferences/locale/FormatSettingsView.cpp @@ -361,16 +361,16 @@ FormatSettingsView::_UpdateExamples() time_t timeValue = (time_t)time(NULL); BString result; - BDateFormat::Default()->Format(&result, timeValue, B_FULL_DATE_FORMAT); + BDateFormat::Default()->Format(result, timeValue, B_FULL_DATE_FORMAT); fFullDateExampleView->SetText(result); - BDateFormat::Default()->Format(&result, timeValue, B_LONG_DATE_FORMAT); + BDateFormat::Default()->Format(result, timeValue, B_LONG_DATE_FORMAT); fLongDateExampleView->SetText(result); - BDateFormat::Default()->Format(&result, timeValue, B_MEDIUM_DATE_FORMAT); + BDateFormat::Default()->Format(result, timeValue, B_MEDIUM_DATE_FORMAT); fMediumDateExampleView->SetText(result); - BDateFormat::Default()->Format(&result, timeValue, B_SHORT_DATE_FORMAT); + BDateFormat::Default()->Format(result, timeValue, B_SHORT_DATE_FORMAT); fShortDateExampleView->SetText(result); BLocale::Default()->FormatTime(&result, timeValue, B_FULL_TIME_FORMAT); diff --git a/src/preferences/time/DateTimeEdit.cpp b/src/preferences/time/DateTimeEdit.cpp index eb2dcc9..b54af09 100644 --- a/src/preferences/time/DateTimeEdit.cpp +++ b/src/preferences/time/DateTimeEdit.cpp @@ -623,7 +623,7 @@ TDateEdit::_UpdateFields() free(fFieldPositions); fFieldPositions = NULL; } - BDateFormat::Default()->Format(&fText, fFieldPositions, fFieldPosCount, + BDateFormat::Default()->Format(fText, fFieldPositions, fFieldPosCount, time, B_SHORT_DATE_FORMAT); if (fFields != NULL) { diff --git a/src/preferences/time/TimeZoneListView.cpp b/src/preferences/time/TimeZoneListView.cpp index 61ca51c..e690201 100644 --- a/src/preferences/time/TimeZoneListView.cpp +++ b/src/preferences/time/TimeZoneListView.cpp @@ -51,7 +51,7 @@ TimeZoneListView::GetToolTipAt(BPoint point, BToolTip** _tip) &item->TimeZone()); BString dateInTimeZone; - BDateFormat::Default()->Format(&dateInTimeZone, now, B_SHORT_DATE_FORMAT, + BDateFormat::Default()->Format(dateInTimeZone, now, B_SHORT_DATE_FORMAT, &item->TimeZone()); BString toolTip = item->Text();