1 /* 2 * Copyright 2014 Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "StringFormatTest.h" 8 9 #include <Locale.h> 10 #include <StringFormat.h> 11 12 #include <cppunit/TestCaller.h> 13 #include <cppunit/TestSuite.h> 14 15 16 StringFormatTest::StringFormatTest() 17 { 18 } 19 20 21 StringFormatTest::~StringFormatTest() 22 { 23 } 24 25 26 void 27 StringFormatTest::TestFormat() 28 { 29 BString output; 30 31 struct Test { 32 const char* locale; 33 const char* pattern; 34 int32 number; 35 const char* expected; 36 }; 37 38 static const char* polishTemplate = "{0, plural, one{Wybrano # obiekt} " 39 "few{Wybrano # obiekty} many{Wybrano # obiektów} " 40 "other{Wybrano # obyektu}}"; 41 42 // There are 4 rules in russian: one (1, 21, ...), few (2-4, 22-24, ...), 43 // many (anything else), and other (non-integer numbers). When formatting 44 // integers only, either both many and other must be there (with other 45 // not being used), or one/few/other must be used. 46 static const char* russianTemplate = "{0, plural, one{# объект} " 47 "few{# объекта} other{# объектов}}"; 48 49 static const Test tests[] = { 50 {"en_US", "A QA engineer walks into a bar.", 0, 51 "A QA engineer walks into a bar."}, 52 {"en_US", "Orders {0, plural, one{# beer} other{# beers}}.", 1, 53 "Orders 1 beer."}, 54 {"en_US", "Orders {0, plural, one{# beer} other{# beers}}.", 0, 55 "Orders 0 beers."}, 56 {"en_US", "Orders {0, plural, one{# beer} other{# beers}}.", 99999999, 57 "Orders 99,999,999 beers."}, 58 {"en_US", "Orders {0, plural, one{# beer} other{# beers}}.", -INT_MAX, 59 "Orders -2,147,483,647 beers."}, 60 {"en_US", "Orders {0, plural, one{# beer} other{# beers}}.", -1, 61 "Orders -1 beer."}, 62 {"en_US", "Orders {0, plural, one{a lizard} other{more lizards}}.", 1, 63 "Orders a lizard."}, 64 {"en_US", "Orders {0, plural, one{a lizard} other{more lizards}}.", 2, 65 "Orders more lizards."}, 66 {"en_US", "Orders {0, plural, one{# \x8A} other{# \x02}}.", 2, 67 "Orders 2 \x02."}, 68 {"fr_FR", "Commande {0, plural, one{# bière} other{# bières}}.", 69 99999999, "Commande 99 999 999 bières."}, 70 {"pl_PL", polishTemplate, 1, "Wybrano 1 obiekt"}, 71 {"pl_PL", polishTemplate, 3, "Wybrano 3 obiekty"}, 72 {"pl_PL", polishTemplate, 5, "Wybrano 5 obiektów"}, 73 {"pl_PL", polishTemplate, 23, "Wybrano 23 obiekty"}, 74 {"ru_RU", russianTemplate, 1, "1 объект"}, 75 {"ru_RU", russianTemplate, 2, "2 объекта"}, 76 {"ru_RU", russianTemplate, 5, "5 объектов"}, 77 {NULL, NULL, 0, NULL} 78 }; 79 80 for (int i = 0; tests[i].pattern != NULL; i++) { 81 status_t result; 82 NextSubTest(); 83 output.Truncate(0); 84 BLanguage language(tests[i].locale); 85 BStringFormat formatter(language, tests[i].pattern); 86 87 result = formatter.Format(output, tests[i].number); 88 CPPUNIT_ASSERT_EQUAL(B_OK, result); 89 CPPUNIT_ASSERT_EQUAL(BString(tests[i].expected), output); 90 } 91 } 92 93 94 void 95 StringFormatTest::TestBogus() 96 { 97 struct Test { 98 const char* pattern; 99 }; 100 101 static const Test tests[] = { 102 { "{0, plural, one{# dog} other{# dogs}" }, // Missing closing brace 103 { "{0, plural, one{# dog}, other{# dogs}}" }, // Extra comma 104 { "{0, plural, one{# dog}" }, // Missing "other" 105 //{ "{4099, plural, one{# dog} other{# dogs}}" }, // Out of bounds arg 106 { "{0, invalid, one{# dog} other{# dogs}}" }, // Invalid rule 107 { NULL } 108 }; 109 110 for (int i = 0; tests[i].pattern != NULL; i++) { 111 NextSubTest(); 112 113 status_t result; 114 BString output; 115 116 BStringFormat formatter(tests[i].pattern); 117 CPPUNIT_ASSERT(formatter.InitCheck() != B_OK); 118 119 result = formatter.Format(output, 1); 120 CPPUNIT_ASSERT(result != B_OK); 121 122 result = formatter.Format(output, 2); 123 CPPUNIT_ASSERT(result != B_OK); 124 } 125 } 126 127 128 /*static*/ void 129 StringFormatTest::AddTests(BTestSuite& parent) 130 { 131 CppUnit::TestSuite& suite = *new CppUnit::TestSuite("StringFormatTest"); 132 133 suite.addTest(new CppUnit::TestCaller<StringFormatTest>( 134 "StringFormatTest::TestFormat", &StringFormatTest::TestFormat)); 135 suite.addTest(new CppUnit::TestCaller<StringFormatTest>( 136 "StringFormatTest::TestBogus", &StringFormatTest::TestBogus)); 137 138 parent.addTest("StringFormatTest", &suite); 139 } 140