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
32extern IntlTest *createBytesTrieTest();
33static IntlTest *createLocalPointerTest();
34extern IntlTest *createUCharsTrieTest();
35static IntlTest *createEnumSetTest();
36extern IntlTest *createLRUCacheTest();
37extern 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
48void 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
120void 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
129static void RefPlusOne(UErrorCode &code) { code=(UErrorCode)(code+1); }
130static void PtrPlusTwo(UErrorCode *code) { *code=(UErrorCode)(*code+2); }
131
132void 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
161class MyErrorCode: public ErrorCode {
162public:
163    MyErrorCode(int32_t &countChecks, int32_t &countDests)
164        : checks(countChecks), dests(countDests) {}
165    ~MyErrorCode() {
166        if(isFailure()) {
167            ++dests;
168        }
169    }
170private:
171    virtual void handleFailure() const {
172        ++checks;
173    }
174    int32_t &checks;
175    int32_t &dests;
176};
177
178void 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
236class LocalPointerTest : public IntlTest {
237public:
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
248static IntlTest *createLocalPointerTest() {
249    return new LocalPointerTest();
250}
251
252void 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.
268void 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).
298void 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.
327void 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.
435void 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
500class EnumSetTest : public IntlTest {
501public:
502  EnumSetTest() {}
503  virtual void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=NULL);
504  void TestEnumSet();
505};
506
507static IntlTest *createEnumSetTest() {
508    return new EnumSetTest();
509}
510
511void 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}
516enum myEnum {
517    MAX_NONBOOLEAN=-1,
518    THING1,
519    THING2,
520    THING3,
521    LIMIT_BOOLEAN
522};
523
524void 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