1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1997-2014, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ********************************************************************/ 6 7 8 /** 9 * IntlTestUtilities is the medium level test class for everything in the directory "utility". 10 */ 11 12 #include "unicode/utypes.h" 13 #include "unicode/errorcode.h" 14 #include "unicode/localpointer.h" 15 #include "itutil.h" 16 #include "strtest.h" 17 #include "loctest.h" 18 #include "citrtest.h" 19 #include "ustrtest.h" 20 #include "ucdtest.h" 21 #include "restest.h" 22 #include "restsnew.h" 23 #include "tsmthred.h" 24 #include "tsputil.h" 25 #include "uobjtest.h" 26 #include "utxttest.h" 27 #include "v32test.h" 28 #include "uvectest.h" 29 #include "aliastst.h" 30 #include "usettest.h" 31 32 extern IntlTest *createBytesTrieTest(); 33 static IntlTest *createLocalPointerTest(); 34 extern IntlTest *createUCharsTrieTest(); 35 static IntlTest *createEnumSetTest(); 36 extern IntlTest *createLRUCacheTest(); 37 extern IntlTest *createSimplePatternFormatterTest(); 38 39 #define CASE(id, test) case id: \ 40 name = #test; \ 41 if (exec) { \ 42 logln(#test "---"); logln(); \ 43 test t; \ 44 callTest(t, par); \ 45 } \ 46 break 47 48 void IntlTestUtilities::runIndexedTest( int32_t index, UBool exec, const char* &name, char* par ) 49 { 50 if (exec) logln("TestSuite Utilities: "); 51 switch (index) { 52 CASE(0, MultithreadTest); 53 CASE(1, StringTest); 54 CASE(2, UnicodeStringTest); 55 CASE(3, LocaleTest); 56 CASE(4, CharIterTest); 57 CASE(5, UObjectTest); 58 CASE(6, UnicodeTest); 59 CASE(7, ResourceBundleTest); 60 CASE(8, NewResourceBundleTest); 61 CASE(9, PUtilTest); 62 CASE(10, UVector32Test); 63 CASE(11, UVectorTest); 64 CASE(12, UTextTest); 65 CASE(13, LocaleAliasTest); 66 CASE(14, UnicodeSetTest); 67 CASE(15, ErrorCodeTest); 68 case 16: 69 name = "LocalPointerTest"; 70 if (exec) { 71 logln("TestSuite LocalPointerTest---"); logln(); 72 LocalPointer<IntlTest> test(createLocalPointerTest()); 73 callTest(*test, par); 74 } 75 break; 76 case 17: 77 name = "BytesTrieTest"; 78 if (exec) { 79 logln("TestSuite BytesTrieTest---"); logln(); 80 LocalPointer<IntlTest> test(createBytesTrieTest()); 81 callTest(*test, par); 82 } 83 break; 84 case 18: 85 name = "UCharsTrieTest"; 86 if (exec) { 87 logln("TestSuite UCharsTrieTest---"); logln(); 88 LocalPointer<IntlTest> test(createUCharsTrieTest()); 89 callTest(*test, par); 90 } 91 break; 92 case 19: 93 name = "EnumSetTest"; 94 if (exec) { 95 logln("TestSuite EnumSetTest---"); logln(); 96 LocalPointer<IntlTest> test(createEnumSetTest()); 97 callTest(*test, par); 98 } 99 break; 100 case 20: 101 name = "LRUCacheTest"; 102 if (exec) { 103 logln("TestSuite LRUCacheTest---"); logln(); 104 LocalPointer<IntlTest> test(createLRUCacheTest()); 105 callTest(*test, par); 106 } 107 break; 108 case 21: 109 name = "SimplePatternFormatterTest"; 110 if (exec) { 111 logln("TestSuite SimplePatternFormatterTest---"); logln(); 112 LocalPointer<IntlTest> test(createSimplePatternFormatterTest()); 113 callTest(*test, par); 114 } 115 break; 116 default: name = ""; break; //needed to end loop 117 } 118 } 119 120 void ErrorCodeTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/) { 121 if (exec) logln("TestSuite Utilities: "); 122 switch (index) { 123 case 0: name = "TestErrorCode"; if (exec) TestErrorCode(); break; 124 case 1: name = "TestSubclass"; if (exec) TestSubclass(); break; 125 default: name = ""; break; //needed to end loop 126 } 127 } 128 129 static void RefPlusOne(UErrorCode &code) { code=(UErrorCode)(code+1); } 130 static void PtrPlusTwo(UErrorCode *code) { *code=(UErrorCode)(*code+2); } 131 132 void ErrorCodeTest::TestErrorCode() { 133 ErrorCode errorCode; 134 if(errorCode.get()!=U_ZERO_ERROR || !errorCode.isSuccess() || errorCode.isFailure()) { 135 errln("ErrorCode did not initialize properly"); 136 return; 137 } 138 errorCode.assertSuccess(); 139 if(errorCode.errorName()!=u_errorName(U_ZERO_ERROR)) { 140 errln("ErrorCode did not format error message string properly"); 141 } 142 RefPlusOne(errorCode); 143 if(errorCode.get()!=U_ILLEGAL_ARGUMENT_ERROR || errorCode.isSuccess() || !errorCode.isFailure()) { 144 errln("ErrorCode did not yield a writable reference"); 145 } 146 PtrPlusTwo(errorCode); 147 if(errorCode.get()!=U_INVALID_FORMAT_ERROR || errorCode.isSuccess() || !errorCode.isFailure()) { 148 errln("ErrorCode did not yield a writable pointer"); 149 } 150 errorCode.set(U_PARSE_ERROR); 151 if(errorCode.get()!=U_PARSE_ERROR || errorCode.isSuccess() || !errorCode.isFailure()) { 152 errln("ErrorCode.set() failed"); 153 } 154 if( errorCode.reset()!=U_PARSE_ERROR || errorCode.get()!=U_ZERO_ERROR || 155 !errorCode.isSuccess() || errorCode.isFailure() 156 ) { 157 errln("ErrorCode did not reset properly"); 158 } 159 } 160 161 class MyErrorCode: public ErrorCode { 162 public: 163 MyErrorCode(int32_t &countChecks, int32_t &countDests) 164 : checks(countChecks), dests(countDests) {} 165 ~MyErrorCode() { 166 if(isFailure()) { 167 ++dests; 168 } 169 } 170 private: 171 virtual void handleFailure() const { 172 ++checks; 173 } 174 int32_t &checks; 175 int32_t &dests; 176 }; 177 178 void ErrorCodeTest::TestSubclass() { 179 int32_t countChecks=0; 180 int32_t countDests=0; 181 { 182 MyErrorCode errorCode(countChecks, countDests); 183 if( errorCode.get()!=U_ZERO_ERROR || !errorCode.isSuccess() || errorCode.isFailure() || 184 countChecks!=0 || countDests!=0 185 ) { 186 errln("ErrorCode did not initialize properly"); 187 return; 188 } 189 errorCode.assertSuccess(); 190 if(countChecks!=0) { 191 errln("ErrorCode.assertSuccess() called handleFailure() despite success"); 192 } 193 RefPlusOne(errorCode); 194 if(errorCode.get()!=U_ILLEGAL_ARGUMENT_ERROR || errorCode.isSuccess() || !errorCode.isFailure()) { 195 errln("ErrorCode did not yield a writable reference"); 196 } 197 errorCode.assertSuccess(); 198 if(countChecks!=1) { 199 errln("ErrorCode.assertSuccess() did not handleFailure()"); 200 } 201 PtrPlusTwo(errorCode); 202 if(errorCode.get()!=U_INVALID_FORMAT_ERROR || errorCode.isSuccess() || !errorCode.isFailure()) { 203 errln("ErrorCode did not yield a writable pointer"); 204 } 205 errorCode.assertSuccess(); 206 if(countChecks!=2) { 207 errln("ErrorCode.assertSuccess() did not handleFailure()"); 208 } 209 errorCode.set(U_PARSE_ERROR); 210 if(errorCode.get()!=U_PARSE_ERROR || errorCode.isSuccess() || !errorCode.isFailure()) { 211 errln("ErrorCode.set() failed"); 212 } 213 if( errorCode.reset()!=U_PARSE_ERROR || errorCode.get()!=U_ZERO_ERROR || 214 !errorCode.isSuccess() || errorCode.isFailure() 215 ) { 216 errln("ErrorCode did not reset properly"); 217 } 218 errorCode.assertSuccess(); 219 if(countChecks!=2) { 220 errln("ErrorCode.assertSuccess() called handleFailure() despite success"); 221 } 222 } 223 if(countDests!=0) { 224 errln("MyErrorCode destructor detected failure despite success"); 225 } 226 countChecks=countDests=0; 227 { 228 MyErrorCode errorCode(countChecks, countDests); 229 errorCode.set(U_PARSE_ERROR); 230 } 231 if(countDests!=1) { 232 errln("MyErrorCode destructor failed to detect failure"); 233 } 234 } 235 236 class LocalPointerTest : public IntlTest { 237 public: 238 LocalPointerTest() {} 239 240 void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=NULL); 241 242 void TestLocalPointer(); 243 void TestLocalArray(); 244 void TestLocalXyzPointer(); 245 void TestLocalXyzPointerNull(); 246 }; 247 248 static IntlTest *createLocalPointerTest() { 249 return new LocalPointerTest(); 250 } 251 252 void LocalPointerTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) { 253 if(exec) { 254 logln("TestSuite LocalPointerTest: "); 255 } 256 switch (index) { 257 TESTCASE(0, TestLocalPointer); 258 TESTCASE(1, TestLocalArray); 259 TESTCASE(2, TestLocalXyzPointer); 260 TESTCASE(3, TestLocalXyzPointerNull); 261 default: 262 name=""; 263 break; // needed to end the loop 264 } 265 } 266 267 // Exercise every LocalPointer and LocalPointerBase method. 268 void LocalPointerTest::TestLocalPointer() { 269 // constructor 270 LocalPointer<UnicodeString> s(new UnicodeString((UChar32)0x50005)); 271 // isNULL(), isValid(), operator==(), operator!=() 272 if(s.isNull() || !s.isValid() || s==NULL || !(s!=NULL)) { 273 errln("LocalPointer constructor or NULL test failure"); 274 return; 275 } 276 // getAlias(), operator->, operator* 277 if(s.getAlias()->length()!=2 || s->length()!=2 || (*s).length()!=2) { 278 errln("LocalPointer access failure"); 279 } 280 // adoptInstead(), orphan() 281 s.adoptInstead(new UnicodeString((UChar)0xfffc)); 282 if(s->length()!=1) { 283 errln("LocalPointer adoptInstead(U+FFFC) failure"); 284 } 285 UnicodeString *orphan=s.orphan(); 286 if(orphan==NULL || orphan->length()!=1 || s.isValid() || s!=NULL) { 287 errln("LocalPointer orphan() failure"); 288 } 289 delete orphan; 290 // destructor 291 s.adoptInstead(new UnicodeString()); 292 if(s->length()!=0) { 293 errln("LocalPointer adoptInstead(empty) failure"); 294 } 295 } 296 297 // Exercise every LocalArray method (but not LocalPointerBase). 298 void LocalPointerTest::TestLocalArray() { 299 // constructor 300 LocalArray<UnicodeString> a(new UnicodeString[2]); 301 // operator[]() 302 a[0].append((UChar)0x61); 303 a[1].append((UChar32)0x60006); 304 if(a[0].length()!=1 || a[1].length()!=2) { 305 errln("LocalArray access failure"); 306 } 307 // adoptInstead() 308 a.adoptInstead(new UnicodeString[4]); 309 a[3].append((UChar)0x62).append((UChar)0x63).reverse(); 310 if(a[3].length()!=2 || a[3][1]!=0x62) { 311 errln("LocalArray adoptInstead() failure"); 312 } 313 // destructor 314 } 315 316 #include "unicode/ucnvsel.h" 317 #include "unicode/ucal.h" 318 #include "unicode/udatpg.h" 319 #include "unicode/uidna.h" 320 #include "unicode/uldnames.h" 321 #include "unicode/umsg.h" 322 #include "unicode/unorm2.h" 323 #include "unicode/uregex.h" 324 #include "unicode/utrans.h" 325 326 // Use LocalXyzPointer types that are not covered elsewhere in the intltest suite. 327 void LocalPointerTest::TestLocalXyzPointer() { 328 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointer"); 329 330 static const char *const encoding="ISO-8859-1"; 331 LocalUConverterSelectorPointer sel( 332 ucnvsel_open(&encoding, 1, NULL, UCNV_ROUNDTRIP_SET, errorCode)); 333 if(errorCode.logIfFailureAndReset("ucnvsel_open()")) { 334 return; 335 } 336 if(sel.isNull()) { 337 errln("LocalUConverterSelectorPointer failure"); 338 return; 339 } 340 341 #if !UCONFIG_NO_FORMATTING 342 LocalUCalendarPointer cal(ucal_open(NULL, 0, "root", UCAL_GREGORIAN, errorCode)); 343 if(errorCode.logDataIfFailureAndReset("ucal_open()")) { 344 return; 345 } 346 if(cal.isNull()) { 347 errln("LocalUCalendarPointer failure"); 348 return; 349 } 350 351 LocalUDateTimePatternGeneratorPointer patgen(udatpg_open("root", errorCode)); 352 if(errorCode.logDataIfFailureAndReset("udatpg_open()")) { 353 return; 354 } 355 if(patgen.isNull()) { 356 errln("LocalUDateTimePatternGeneratorPointer failure"); 357 return; 358 } 359 360 LocalULocaleDisplayNamesPointer ldn(uldn_open("de-CH", ULDN_STANDARD_NAMES, errorCode)); 361 if(errorCode.logIfFailureAndReset("uldn_open()")) { 362 return; 363 } 364 if(ldn.isNull()) { 365 errln("LocalULocaleDisplayNamesPointer failure"); 366 return; 367 } 368 369 UnicodeString hello=UNICODE_STRING_SIMPLE("Hello {0}!"); 370 LocalUMessageFormatPointer msg( 371 umsg_open(hello.getBuffer(), hello.length(), "root", NULL, errorCode)); 372 if(errorCode.logIfFailureAndReset("umsg_open()")) { 373 return; 374 } 375 if(msg.isNull()) { 376 errln("LocalUMessageFormatPointer failure"); 377 return; 378 } 379 #endif /* UCONFIG_NO_FORMATTING */ 380 381 #if !UCONFIG_NO_NORMALIZATION 382 const UNormalizer2 *nfc=unorm2_getNFCInstance(errorCode); 383 UnicodeSet emptySet; 384 LocalUNormalizer2Pointer fn2(unorm2_openFiltered(nfc, emptySet.toUSet(), errorCode)); 385 if(errorCode.logIfFailureAndReset("unorm2_openFiltered()")) { 386 return; 387 } 388 if(fn2.isNull()) { 389 errln("LocalUNormalizer2Pointer failure"); 390 return; 391 } 392 #endif /* !UCONFIG_NO_NORMALIZATION */ 393 394 #if !UCONFIG_NO_IDNA 395 LocalUIDNAPointer idna(uidna_openUTS46(0, errorCode)); 396 if(errorCode.logIfFailureAndReset("uidna_openUTS46()")) { 397 return; 398 } 399 if(idna.isNull()) { 400 errln("LocalUIDNAPointer failure"); 401 return; 402 } 403 #endif /* !UCONFIG_NO_IDNA */ 404 405 #if !UCONFIG_NO_REGULAR_EXPRESSIONS 406 UnicodeString pattern=UNICODE_STRING_SIMPLE("abc|xy+z"); 407 LocalURegularExpressionPointer regex( 408 uregex_open(pattern.getBuffer(), pattern.length(), 0, NULL, errorCode)); 409 if(errorCode.logIfFailureAndReset("uregex_open()")) { 410 return; 411 } 412 if(regex.isNull()) { 413 errln("LocalURegularExpressionPointer failure"); 414 return; 415 } 416 #endif /* UCONFIG_NO_REGULAR_EXPRESSIONS */ 417 418 #if !UCONFIG_NO_TRANSLITERATION 419 UnicodeString id=UNICODE_STRING_SIMPLE("Grek-Latn"); 420 LocalUTransliteratorPointer trans( 421 utrans_openU(id.getBuffer(), id.length(), UTRANS_FORWARD, NULL, 0, NULL, errorCode)); 422 if(errorCode.logIfFailureAndReset("utrans_open()")) { 423 return; 424 } 425 if(trans.isNull()) { 426 errln("LocalUTransliteratorPointer failure"); 427 return; 428 } 429 #endif /* !UCONFIG_NO_TRANSLITERATION */ 430 431 // destructors 432 } 433 434 // Try LocalXyzPointer types with NULL pointers. 435 void LocalPointerTest::TestLocalXyzPointerNull() { 436 { 437 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerNull/LocalUConverterSelectorPointer"); 438 static const char *const encoding="ISO-8859-1"; 439 LocalUConverterSelectorPointer null; 440 LocalUConverterSelectorPointer sel( 441 ucnvsel_open(&encoding, 1, NULL, UCNV_ROUNDTRIP_SET, errorCode)); 442 sel.adoptInstead(NULL); 443 } 444 #if !UCONFIG_NO_FORMATTING 445 { 446 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerNull/LocalUCalendarPointer"); 447 LocalUCalendarPointer null; 448 LocalUCalendarPointer cal(ucal_open(NULL, 0, "root", UCAL_GREGORIAN, errorCode)); 449 if(!errorCode.logDataIfFailureAndReset("ucal_open()")) { 450 cal.adoptInstead(NULL); 451 } 452 } 453 { 454 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerNull/LocalUDateTimePatternGeneratorPointer"); 455 LocalUDateTimePatternGeneratorPointer null; 456 LocalUDateTimePatternGeneratorPointer patgen(udatpg_open("root", errorCode)); 457 patgen.adoptInstead(NULL); 458 } 459 { 460 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerNull/LocalUMessageFormatPointer"); 461 UnicodeString hello=UNICODE_STRING_SIMPLE("Hello {0}!"); 462 LocalUMessageFormatPointer null; 463 LocalUMessageFormatPointer msg( 464 umsg_open(hello.getBuffer(), hello.length(), "root", NULL, errorCode)); 465 msg.adoptInstead(NULL); 466 } 467 #endif /* !UCONFIG_NO_FORMATTING */ 468 469 #if !UCONFIG_NO_REGULAR_EXPRESSIONS 470 { 471 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerNull/LocalURegularExpressionPointer"); 472 UnicodeString pattern=UNICODE_STRING_SIMPLE("abc|xy+z"); 473 LocalURegularExpressionPointer null; 474 LocalURegularExpressionPointer regex( 475 uregex_open(pattern.getBuffer(), pattern.length(), 0, NULL, errorCode)); 476 if(!errorCode.logDataIfFailureAndReset("urege_open()")) { 477 regex.adoptInstead(NULL); 478 } 479 } 480 #endif /* !UCONFIG_NO_REGULAR_EXPRESSIONS */ 481 482 #if !UCONFIG_NO_TRANSLITERATION 483 { 484 IcuTestErrorCode errorCode(*this, "TestLocalXyzPointerNull/LocalUTransliteratorPointer"); 485 UnicodeString id=UNICODE_STRING_SIMPLE("Grek-Latn"); 486 LocalUTransliteratorPointer null; 487 LocalUTransliteratorPointer trans( 488 utrans_openU(id.getBuffer(), id.length(), UTRANS_FORWARD, NULL, 0, NULL, errorCode)); 489 if(!errorCode.logDataIfFailureAndReset("utrans_openU()")) { 490 trans.adoptInstead(NULL); 491 } 492 } 493 #endif /* !UCONFIG_NO_TRANSLITERATION */ 494 495 } 496 497 /** EnumSet test **/ 498 #include "unicode/enumset.h" 499 500 class EnumSetTest : public IntlTest { 501 public: 502 EnumSetTest() {} 503 virtual void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=NULL); 504 void TestEnumSet(); 505 }; 506 507 static IntlTest *createEnumSetTest() { 508 return new EnumSetTest(); 509 } 510 511 void EnumSetTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) { 512 TESTCASE_AUTO_BEGIN; 513 TESTCASE_AUTO(TestEnumSet); 514 TESTCASE_AUTO_END; 515 } 516 enum myEnum { 517 MAX_NONBOOLEAN=-1, 518 THING1, 519 THING2, 520 THING3, 521 LIMIT_BOOLEAN 522 }; 523 524 void EnumSetTest::TestEnumSet() { 525 EnumSet<myEnum, 526 MAX_NONBOOLEAN+1, 527 LIMIT_BOOLEAN> 528 flags; 529 530 logln("Enum is from [%d..%d]\n", MAX_NONBOOLEAN+1, 531 LIMIT_BOOLEAN); 532 533 TEST_ASSERT_TRUE(flags.get(THING1) == FALSE); 534 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 535 TEST_ASSERT_TRUE(flags.get(THING3) == FALSE); 536 537 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 538 logln("Value now: %d\n", flags.getAll()); 539 flags.clear(); 540 logln("clear -Value now: %d\n", flags.getAll()); 541 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 542 TEST_ASSERT_TRUE(flags.get(THING1) == FALSE); 543 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 544 TEST_ASSERT_TRUE(flags.get(THING3) == FALSE); 545 flags.add(THING1); 546 logln("set THING1 -Value now: %d\n", flags.getAll()); 547 TEST_ASSERT_TRUE(flags.get(THING1) == TRUE); 548 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 549 TEST_ASSERT_TRUE(flags.get(THING3) == FALSE); 550 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 551 flags.add(THING3); 552 logln("set THING3 -Value now: %d\n", flags.getAll()); 553 TEST_ASSERT_TRUE(flags.get(THING1) == TRUE); 554 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 555 TEST_ASSERT_TRUE(flags.get(THING3) == TRUE); 556 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 557 flags.remove(THING2); 558 TEST_ASSERT_TRUE(flags.get(THING1) == TRUE); 559 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 560 TEST_ASSERT_TRUE(flags.get(THING3) == TRUE); 561 logln("remove THING2 -Value now: %d\n", flags.getAll()); 562 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 563 flags.remove(THING1); 564 TEST_ASSERT_TRUE(flags.get(THING1) == FALSE); 565 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 566 TEST_ASSERT_TRUE(flags.get(THING3) == TRUE); 567 logln("remove THING1 -Value now: %d\n", flags.getAll()); 568 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 569 570 flags.clear(); 571 logln("clear -Value now: %d\n", flags.getAll()); 572 logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(THING1), flags.get(THING2), flags.get(THING3)); 573 TEST_ASSERT_TRUE(flags.get(THING1) == FALSE); 574 TEST_ASSERT_TRUE(flags.get(THING2) == FALSE); 575 TEST_ASSERT_TRUE(flags.get(THING3) == FALSE); 576 } 577