1 /* 2 * Copyright 2014-2021 Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "DateFormatTest.h" 8 9 #include <DateFormat.h> 10 #include <FormattingConventions.h> 11 #include <Language.h> 12 #include <TimeFormat.h> 13 #include <TimeZone.h> 14 15 #include <cppunit/TestCaller.h> 16 #include <cppunit/TestSuite.h> 17 18 19 DateFormatTest::DateFormatTest() 20 { 21 } 22 23 24 DateFormatTest::~DateFormatTest() 25 { 26 } 27 28 29 void 30 DateFormatTest::TestCustomFormat() 31 { 32 struct Test { 33 const char* language; 34 const char* formatting; 35 const char* timeZone; 36 int32 fields; 37 38 BString expected; 39 BString force24; 40 BString force12; 41 }; 42 43 BString buffer; 44 45 const Test tests[] = { 46 { "en", "en_US", "GMT+1", B_DATE_ELEMENT_HOUR | B_DATE_ELEMENT_MINUTE, 47 "10:21 PM", "22:21", "10:21 PM" }, 48 { "en", "en_US", "GMT+1", 49 B_DATE_ELEMENT_HOUR | B_DATE_ELEMENT_MINUTE | B_DATE_ELEMENT_SECOND, 50 "10:21:18 PM", "22:21:18", "10:21:18 PM" }, 51 { "en", "en_US", "GMT+1", B_DATE_ELEMENT_HOUR | B_DATE_ELEMENT_MINUTE 52 | B_DATE_ELEMENT_TIMEZONE, 53 "10:21 PM GMT+1", "22:21 GMT+1", "10:21 PM GMT+1" }, 54 { "en", "en_US", "GMT+1", B_DATE_ELEMENT_HOUR | B_DATE_ELEMENT_MINUTE 55 | B_DATE_ELEMENT_SECOND | B_DATE_ELEMENT_TIMEZONE, 56 "10:21:18 PM GMT+1", "22:21:18 GMT+1", "10:21:18 PM GMT+1" }, 57 { "fr", "fr_FR", "GMT+1", B_DATE_ELEMENT_HOUR | B_DATE_ELEMENT_MINUTE, 58 "22:21", "22:21", "10:21 PM" }, 59 { NULL } 60 }; 61 62 for (int i = 0; tests[i].language != NULL; i++) 63 { 64 NextSubTest(); 65 66 BLanguage language(tests[i].language); 67 BFormattingConventions formatting(tests[i].formatting); 68 BTimeZone timeZone(tests[i].timeZone); 69 status_t result; 70 71 // Test default for language/formatting 72 { 73 BDateTimeFormat format(language, formatting); 74 format.SetDateTimeFormat(B_SHORT_DATE_FORMAT, B_SHORT_TIME_FORMAT, 75 tests[i].fields); 76 77 result = format.Format(buffer, 12345678, B_SHORT_DATE_FORMAT, 78 B_SHORT_TIME_FORMAT, &timeZone); 79 80 CPPUNIT_ASSERT_EQUAL(B_OK, result); 81 CPPUNIT_ASSERT_EQUAL(tests[i].expected, buffer); 82 } 83 84 // Test forced 24 hours 85 { 86 formatting.SetExplicitUse24HourClock(true); 87 BDateTimeFormat format(language, formatting); 88 format.SetDateTimeFormat(B_SHORT_DATE_FORMAT, B_SHORT_TIME_FORMAT, 89 tests[i].fields); 90 result = format.Format(buffer, 12345678, B_SHORT_DATE_FORMAT, 91 B_SHORT_TIME_FORMAT, &timeZone); 92 93 CPPUNIT_ASSERT_EQUAL(B_OK, result); 94 CPPUNIT_ASSERT_EQUAL(tests[i].force24, buffer); 95 } 96 97 // Test forced 12 hours 98 { 99 formatting.SetExplicitUse24HourClock(false); 100 BDateTimeFormat format(language, formatting); 101 format.SetDateTimeFormat(B_SHORT_DATE_FORMAT, B_SHORT_TIME_FORMAT, 102 tests[i].fields); 103 result = format.Format(buffer, 12345678, B_SHORT_DATE_FORMAT, 104 B_SHORT_TIME_FORMAT, &timeZone); 105 106 CPPUNIT_ASSERT_EQUAL(B_OK, result); 107 CPPUNIT_ASSERT_EQUAL(tests[i].force12, buffer); 108 } 109 } 110 } 111 112 113 void 114 DateFormatTest::TestFormat() 115 { 116 struct Value { 117 const char* language; 118 const char* convention; 119 const char* timeZone; 120 time_t time; 121 const char* shortDate; 122 const char* longDate; 123 const char* shortTime; 124 const char* longTime; 125 const char* shortDateTime; 126 }; 127 128 static const Value values[] = { 129 {"en", "en_US", "GMT+1", 12345, "1/1/70", "January 1, 1970", 130 "4:25 AM", "4:25:45 AM", "1/1/70, 4:25 AM"}, 131 {"fr", "fr_FR", "GMT+1", 12345, "01/01/1970", "1 janvier 1970", 132 "04:25", "04:25:45", "01/01/1970 04:25"}, 133 {"fr", "fr_FR", "GMT+1", 12345678, "23/05/1970", "23 mai 1970", 134 "22:21", "22:21:18", "23/05/1970 22:21"}, 135 {NULL} 136 }; 137 138 BString output; 139 status_t result; 140 141 for (int i = 0; values[i].language != NULL; i++) { 142 NextSubTest(); 143 144 BLanguage language(values[i].language); 145 BFormattingConventions formatting(values[i].convention); 146 BTimeZone timeZone(values[i].timeZone); 147 BDateFormat dateFormat(language, formatting); 148 BTimeFormat timeFormat(language, formatting); 149 BDateTimeFormat dateTimeFormat(language, formatting); 150 151 result = dateFormat.Format(output, values[i].time, B_SHORT_DATE_FORMAT, 152 &timeZone); 153 CPPUNIT_ASSERT_EQUAL(B_OK, result); 154 CPPUNIT_ASSERT_EQUAL(BString(values[i].shortDate), output); 155 156 result = dateFormat.Format(output, values[i].time, B_LONG_DATE_FORMAT, 157 &timeZone); 158 CPPUNIT_ASSERT_EQUAL(B_OK, result); 159 CPPUNIT_ASSERT_EQUAL(BString(values[i].longDate), output); 160 161 result = timeFormat.Format(output, values[i].time, B_SHORT_TIME_FORMAT, 162 &timeZone); 163 CPPUNIT_ASSERT_EQUAL(B_OK, result); 164 CPPUNIT_ASSERT_EQUAL(BString(values[i].shortTime), output); 165 166 result = timeFormat.Format(output, values[i].time, B_MEDIUM_TIME_FORMAT, 167 &timeZone); 168 CPPUNIT_ASSERT_EQUAL(B_OK, result); 169 CPPUNIT_ASSERT_EQUAL(BString(values[i].longTime), output); 170 171 result = dateTimeFormat.Format(output, values[i].time, 172 B_SHORT_DATE_FORMAT, B_SHORT_TIME_FORMAT, &timeZone); 173 CPPUNIT_ASSERT_EQUAL(B_OK, result); 174 CPPUNIT_ASSERT_EQUAL(BString(values[i].shortDateTime), output); 175 } 176 } 177 178 179 void 180 DateFormatTest::TestFormatDate() 181 { 182 BLanguage language("en"); 183 BFormattingConventions formatting("en_US"); 184 BDateFormat format(language, formatting); 185 186 BString output; 187 status_t result; 188 189 BDate date(2014, 9, 29); 190 191 result = format.Format(output, date, B_LONG_DATE_FORMAT); 192 CPPUNIT_ASSERT_EQUAL(B_OK, result); 193 CPPUNIT_ASSERT_EQUAL(BString("September 29, 2014"), output); 194 195 // Test an invalid date - must return B_BAD_DATA 196 date.SetDate(2014, 29, 29); 197 result = format.Format(output, date, B_LONG_DATE_FORMAT); 198 CPPUNIT_ASSERT_EQUAL(B_BAD_DATA, result); 199 } 200 201 202 void 203 DateFormatTest::TestMonthNames() 204 { 205 BLanguage language("en"); 206 BFormattingConventions formatting("en_US"); 207 BDateFormat format(language, formatting); 208 209 BString buffer; 210 status_t result = format.GetMonthName(1, buffer); 211 212 CPPUNIT_ASSERT_EQUAL(BString("January"), buffer); 213 CPPUNIT_ASSERT_EQUAL(B_OK, result); 214 215 buffer.Truncate(0); 216 result = format.GetMonthName(12, buffer); 217 218 CPPUNIT_ASSERT_EQUAL(BString("December"), buffer); 219 CPPUNIT_ASSERT_EQUAL(B_OK, result); 220 221 buffer.Truncate(0); 222 result = format.GetMonthName(1, buffer, B_FULL_DATE_FORMAT); 223 224 CPPUNIT_ASSERT_EQUAL(BString("January"), buffer); 225 CPPUNIT_ASSERT_EQUAL(B_OK, result); 226 227 buffer.Truncate(0); 228 result = format.GetMonthName(12, buffer, B_FULL_DATE_FORMAT); 229 230 CPPUNIT_ASSERT_EQUAL(BString("December"), buffer); 231 CPPUNIT_ASSERT_EQUAL(B_OK, result); 232 233 buffer.Truncate(0); 234 result = format.GetMonthName(1, buffer, B_LONG_DATE_FORMAT); 235 236 CPPUNIT_ASSERT_EQUAL(BString("Jan"), buffer); 237 CPPUNIT_ASSERT_EQUAL(B_OK, result); 238 239 buffer.Truncate(0); 240 result = format.GetMonthName(12, buffer, B_LONG_DATE_FORMAT); 241 242 CPPUNIT_ASSERT_EQUAL(BString("Dec"), buffer); 243 CPPUNIT_ASSERT_EQUAL(B_OK, result); 244 245 buffer.Truncate(0); 246 result = format.GetMonthName(1, buffer, B_MEDIUM_DATE_FORMAT); 247 248 CPPUNIT_ASSERT_EQUAL(BString("Jan"), buffer); 249 CPPUNIT_ASSERT_EQUAL(B_OK, result); 250 251 buffer.Truncate(0); 252 result = format.GetMonthName(12, buffer, B_MEDIUM_DATE_FORMAT); 253 254 CPPUNIT_ASSERT_EQUAL(BString("Dec"), buffer); 255 CPPUNIT_ASSERT_EQUAL(B_OK, result); 256 257 buffer.Truncate(0); 258 result = format.GetMonthName(1, buffer, B_SHORT_DATE_FORMAT); 259 260 CPPUNIT_ASSERT_EQUAL(BString("J"), buffer); 261 CPPUNIT_ASSERT_EQUAL(B_OK, result); 262 263 buffer.Truncate(0); 264 result = format.GetMonthName(12, buffer, B_SHORT_DATE_FORMAT); 265 266 CPPUNIT_ASSERT_EQUAL(BString("D"), buffer); 267 CPPUNIT_ASSERT_EQUAL(B_OK, result); 268 269 } 270 271 272 void 273 DateFormatTest::TestDayNames() 274 { 275 BLanguage language("en"); 276 BFormattingConventions formatting("en_US"); 277 BDateFormat format(language, formatting); 278 279 BString buffer; 280 status_t result = format.GetDayName(1, buffer); 281 282 CPPUNIT_ASSERT_EQUAL(BString("Monday"), buffer); 283 CPPUNIT_ASSERT_EQUAL(B_OK, result); 284 285 buffer.Truncate(0); 286 result = format.GetDayName(2, buffer); 287 288 CPPUNIT_ASSERT_EQUAL(BString("Tuesday"), buffer); 289 CPPUNIT_ASSERT_EQUAL(B_OK, result); 290 291 buffer.Truncate(0); 292 result = format.GetDayName(1, buffer, B_FULL_DATE_FORMAT); 293 294 CPPUNIT_ASSERT_EQUAL(BString("Monday"), buffer); 295 CPPUNIT_ASSERT_EQUAL(B_OK, result); 296 297 buffer.Truncate(0); 298 result = format.GetDayName(2, buffer, B_FULL_DATE_FORMAT); 299 300 CPPUNIT_ASSERT_EQUAL(BString("Tuesday"), buffer); 301 CPPUNIT_ASSERT_EQUAL(B_OK, result); 302 303 buffer.Truncate(0); 304 result = format.GetDayName(1, buffer, B_LONG_DATE_FORMAT); 305 306 CPPUNIT_ASSERT_EQUAL(BString("Mon"), buffer); 307 CPPUNIT_ASSERT_EQUAL(B_OK, result); 308 309 buffer.Truncate(0); 310 result = format.GetDayName(2, buffer, B_LONG_DATE_FORMAT); 311 312 CPPUNIT_ASSERT_EQUAL(BString("Tue"), buffer); 313 CPPUNIT_ASSERT_EQUAL(B_OK, result); 314 315 buffer.Truncate(0); 316 result = format.GetDayName(1, buffer, B_MEDIUM_DATE_FORMAT); 317 318 CPPUNIT_ASSERT_EQUAL(BString("Mo"), buffer); 319 CPPUNIT_ASSERT_EQUAL(B_OK, result); 320 321 buffer.Truncate(0); 322 result = format.GetDayName(2, buffer, B_MEDIUM_DATE_FORMAT); 323 324 CPPUNIT_ASSERT_EQUAL(BString("Tu"), buffer); 325 CPPUNIT_ASSERT_EQUAL(B_OK, result); 326 327 buffer.Truncate(0); 328 result = format.GetDayName(1, buffer, B_SHORT_DATE_FORMAT); 329 330 CPPUNIT_ASSERT_EQUAL(BString("M"), buffer); 331 CPPUNIT_ASSERT_EQUAL(B_OK, result); 332 333 buffer.Truncate(0); 334 result = format.GetDayName(2, buffer, B_SHORT_DATE_FORMAT); 335 336 CPPUNIT_ASSERT_EQUAL(BString("T"), buffer); 337 CPPUNIT_ASSERT_EQUAL(B_OK, result); 338 } 339 340 341 namespace BPrivate { 342 343 344 std::ostream& operator<<(std::ostream& stream, const BDate& date) 345 { 346 stream << date.Year(); 347 stream << '-'; 348 stream << date.Month(); 349 stream << '-'; 350 stream << date.Day(); 351 352 return stream; 353 } 354 355 356 std::ostream& operator<<(std::ostream& stream, const BTime& date) 357 { 358 stream << date.Hour(); 359 stream << ':'; 360 stream << date.Minute(); 361 stream << ':'; 362 stream << date.Second(); 363 364 return stream; 365 } 366 367 368 } // namespace BPrivate 369 370 371 void 372 DateFormatTest::TestParseDate() 373 { 374 BLanguage language("en"); 375 BFormattingConventions formatting("en_US"); 376 BDateFormat format(language, formatting); 377 BDate date; 378 status_t result; 379 380 struct Test { 381 const char* input; 382 BDate output; 383 }; 384 385 static const Test tests[] = { 386 {"01/01/1970", BDate(1970, 1, 1)}, 387 {"05/07/1988", BDate(1988, 5, 7)}, 388 {"07/31/2345", BDate(2345, 7, 31)}, 389 {NULL} 390 }; 391 392 for (int i = 0; tests[i].input != NULL; i++) { 393 NextSubTest(); 394 result = format.Parse(tests[i].input, B_SHORT_DATE_FORMAT, date); 395 396 CPPUNIT_ASSERT_EQUAL(tests[i].output, date); 397 CPPUNIT_ASSERT_EQUAL(B_OK, result); 398 } 399 } 400 401 402 void 403 DateFormatTest::TestParseTime() 404 { 405 BLanguage language("fr"); 406 BFormattingConventions formatting("fr_FR"); 407 BTimeFormat format(language, formatting); 408 BTime date; 409 status_t result; 410 411 struct Test { 412 const char* input; 413 BTime output; 414 }; 415 416 static const Test tests[] = { 417 {"03:25", BTime(3, 25, 0)}, 418 {"16:18", BTime(16, 18, 0)}, 419 {"23:59", BTime(23, 59, 0)}, 420 {NULL} 421 }; 422 423 for (int i = 0; tests[i].input != NULL; i++) { 424 NextSubTest(); 425 result = format.Parse(tests[i].input, B_SHORT_TIME_FORMAT, date); 426 427 CPPUNIT_ASSERT_EQUAL(tests[i].output, date); 428 CPPUNIT_ASSERT_EQUAL(B_OK, result); 429 } 430 } 431 432 433 /*static*/ void 434 DateFormatTest::AddTests(BTestSuite& parent) 435 { 436 CppUnit::TestSuite& suite = *new CppUnit::TestSuite("DateFormatTest"); 437 438 suite.addTest(new CppUnit::TestCaller<DateFormatTest>( 439 "DateFormatTest::TestCustomFormat", &DateFormatTest::TestCustomFormat)); 440 suite.addTest(new CppUnit::TestCaller<DateFormatTest>( 441 "DateFormatTest::TestFormat", &DateFormatTest::TestFormat)); 442 suite.addTest(new CppUnit::TestCaller<DateFormatTest>( 443 "DateFormatTest::TestFormatDate", &DateFormatTest::TestFormatDate)); 444 suite.addTest(new CppUnit::TestCaller<DateFormatTest>( 445 "DateFormatTest::TestMonthNames", &DateFormatTest::TestMonthNames)); 446 suite.addTest(new CppUnit::TestCaller<DateFormatTest>( 447 "DateFormatTest::TestDayNames", &DateFormatTest::TestDayNames)); 448 suite.addTest(new CppUnit::TestCaller<DateFormatTest>( 449 "DateFormatTest::TestParseDate", &DateFormatTest::TestParseDate)); 450 suite.addTest(new CppUnit::TestCaller<DateFormatTest>( 451 "DateFormatTest::TestParseTime", &DateFormatTest::TestParseTime)); 452 453 parent.addTest("DateFormatTest", &suite); 454 } 455