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