diff options
Diffstat (limited to 'Build/source/libs/icu/icu-xetex/test/intltest/reptest.cpp')
-rw-r--r-- | Build/source/libs/icu/icu-xetex/test/intltest/reptest.cpp | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-xetex/test/intltest/reptest.cpp b/Build/source/libs/icu/icu-xetex/test/intltest/reptest.cpp new file mode 100644 index 00000000000..d203fed5347 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/test/intltest/reptest.cpp @@ -0,0 +1,322 @@ +/******************************************************************** + * COPYRIGHT: + * Copyright (c) 2001-2005, International Business Machines Corporation and + * others. All Rights Reserved. + ********************************************************************/ +/************************************************************************ +* This test program is intended for testing Replaceable class. +* +* Date Name Description +* 11/28/2001 hshih Ported back from Java. +* +************************************************************************/ + +#include "unicode/utypes.h" + +#if !UCONFIG_NO_TRANSLITERATION + +#include "ittrans.h" +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include "unicode/rep.h" +#include "reptest.h" + +//--------------------------------------------- +// runIndexedTest +//--------------------------------------------- + + /** + * This is a test class that simulates styled text. + * It associates a style number (0..65535) with each character, + * and maintains that style in the normal fashion: + * When setting text from raw string or characters,<br> + * Set the styles to the style of the first character replaced.<br> + * If no characters are replaced, use the style of the previous character.<br> + * If at start, use the following character<br> + * Otherwise use NO_STYLE. + */ +class TestReplaceable : public Replaceable { + UnicodeString chars; + UnicodeString styles; + + static const UChar NO_STYLE; + + static const UChar NO_STYLE_MARK; + + /** + * The address of this static class variable serves as this class's ID + * for ICU "poor man's RTTI". + */ + static const char fgClassID; + +public: + TestReplaceable (const UnicodeString& text, + const UnicodeString& newStyles) { + chars = text; + UnicodeString s; + for (int i = 0; i < text.length(); ++i) { + if (i < newStyles.length()) { + s.append(newStyles.charAt(i)); + } else { + if (text.charAt(i) == NO_STYLE_MARK) { + s.append(NO_STYLE); + } else { + s.append((UChar)(i + 0x0031)); + } + } + } + this->styles = s; + } + + virtual Replaceable *clone() const { + return new TestReplaceable(chars, styles); + } + + ~TestReplaceable(void) {} + + UnicodeString getStyles() { + return styles; + } + + UnicodeString toString() { + UnicodeString s = chars; + s.append("{"); + s.append(styles); + s.append("}"); + return s; + } + + void extractBetween(int32_t start, int32_t limit, UnicodeString& result) const { + chars.extractBetween(start, limit, result); + } + + /** + * ICU "poor man's RTTI", returns a UClassID for this class. + * + * @draft ICU 2.2 + */ + static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } + + /** + * ICU "poor man's RTTI", returns a UClassID for the actual class. + * + * @draft ICU 2.2 + */ + virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); } + +protected: + virtual int32_t getLength() const { + return chars.length(); + } + + virtual UChar getCharAt(int32_t offset) const{ + return chars.charAt(offset); + } + + virtual UChar32 getChar32At(int32_t offset) const{ + return chars.char32At(offset); + } + + void fixStyles(int32_t start, int32_t limit, int32_t newLen) { + UChar newStyle = NO_STYLE; + if (start != limit && styles.charAt(start) != NO_STYLE) { + newStyle = styles.charAt(start); + } else if (start > 0 && getCharAt(start-1) != NO_STYLE_MARK) { + newStyle = styles.charAt(start-1); + } else if (limit < styles.length()) { + newStyle = styles.charAt(limit); + } + // dumb implementation for now. + UnicodeString s; + for (int i = 0; i < newLen; ++i) { + // this doesn't really handle an embedded NO_STYLE_MARK + // in the middle of a long run of characters right -- but + // that case shouldn't happen anyway + if (getCharAt(start+i) == NO_STYLE_MARK) { + s.append(NO_STYLE); + } else { + s.append(newStyle); + } + } + styles.replaceBetween(start, limit, s); + } + + virtual void handleReplaceBetween(int32_t start, int32_t limit, const UnicodeString& text) { + UnicodeString s; + this->extractBetween(start, limit, s); + if (s == text) return; // NO ACTION! + this->chars.replaceBetween(start, limit, text); + fixStyles(start, limit, text.length()); + } + + + virtual void copy(int32_t start, int32_t limit, int32_t dest) { + chars.copy(start, limit, dest); + styles.copy(start, limit, dest); + } +}; + +const char TestReplaceable::fgClassID=0; + +const UChar TestReplaceable::NO_STYLE = 0x005F; + +const UChar TestReplaceable::NO_STYLE_MARK = 0xFFFF; + +void +ReplaceableTest::runIndexedTest(int32_t index, UBool exec, + const char* &name, char* /*par*/) { + switch (index) { + TESTCASE(0,TestReplaceableClass); + default: name = ""; break; + } +} + +/* + * Dummy Replaceable implementation for better API/code coverage. + */ +class NoopReplaceable : public Replaceable { +public: + virtual int32_t getLength() const { + return 0; + } + + virtual UChar getCharAt(int32_t /*offset*/) const{ + return 0xffff; + } + + virtual UChar32 getChar32At(int32_t /*offset*/) const{ + return 0xffff; + } + + void extractBetween(int32_t /*start*/, int32_t /*limit*/, UnicodeString& result) const { + result.remove(); + } + + virtual void handleReplaceBetween(int32_t /*start*/, int32_t /*limit*/, const UnicodeString &/*text*/) { + /* do nothing */ + } + + virtual void copy(int32_t /*start*/, int32_t /*limit*/, int32_t /*dest*/) { + /* do nothing */ + } + + static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } + virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); } + +private: + static const char fgClassID; +}; + +const char NoopReplaceable::fgClassID=0; + +void ReplaceableTest::TestReplaceableClass(void) { + UChar rawTestArray[][6] = { + {0x0041, 0x0042, 0x0043, 0x0044, 0x0000, 0x0000}, // ABCD + {0x0061, 0x0062, 0x0063, 0x0064, 0x00DF, 0x0000}, // abcd\u00DF + {0x0061, 0x0042, 0x0043, 0x0044, 0x0000, 0x0000}, // aBCD + {0x0041, 0x0300, 0x0045, 0x0300, 0x0000, 0x0000}, // A\u0300E\u0300 + {0x00C0, 0x00C8, 0x0000, 0x0000, 0x0000, 0x0000}, // \u00C0\u00C8 + {0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */ + {0x0077, 0x0078, 0x0079, 0x007A, 0x0000, 0x0000}, /* "wxyz" */ + {0x0077, 0x0078, 0x0079, 0x007A, 0x0075, 0x0000}, /* "wxyzu" */ + {0x0078, 0x0079, 0x007A, 0x0000, 0x0000, 0x0000}, /* "xyz" */ + {0x0077, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "wxy" */ + {0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */ + {0xFFFF, 0x0078, 0x0079, 0x0000, 0x0000, 0x0000}, /* "*xy" */ + }; + check("Lower", rawTestArray[0], "1234"); + check("Upper", rawTestArray[1], "123455"); // must map 00DF to SS + check("Title", rawTestArray[2], "1234"); + check("NFC", rawTestArray[3], "13"); + check("NFD", rawTestArray[4], "1122"); + check("*(x) > A $1 B", rawTestArray[5], "11223"); + check("*(x)(y) > A $2 B $1 C $2 D", rawTestArray[6], "113322334"); + check("*(x)(y)(z) > A $3 B $2 C $1 D", rawTestArray[7], "114433225"); + // Disabled for 2.4. TODO Revisit in 2.6 or later. + //check("*x > a", rawTestArray[8], "223"); // expect "123"? + //check("*x > a", rawTestArray[9], "113"); // expect "123"? + //check("*x > a", rawTestArray[10], "_33"); // expect "_23"? + //check("*(x) > A $1 B", rawTestArray[11], "__223"); + + // improve API/code coverage + NoopReplaceable noop; + Replaceable *p; + if((p=noop.clone())!=NULL) { + errln("Replaceable::clone() does not return NULL"); + delete p; + } + + if(!noop.hasMetaData()) { + errln("Replaceable::hasMetaData() does not return TRUE"); + } + + // try to call the compiler-provided + // UMemory/UObject/Replaceable assignment operators + NoopReplaceable noop2; + noop2=noop; + if((p=noop2.clone())!=NULL) { + errln("noop2.Replaceable::clone() does not return NULL"); + delete p; + } + + // try to call the compiler-provided + // UMemory/UObject/Replaceable copy constructors + NoopReplaceable noop3(noop); + if((p=noop3.clone())!=NULL) { + errln("noop3.Replaceable::clone() does not return NULL"); + delete p; + } +} + +void ReplaceableTest::check(const UnicodeString& transliteratorName, + const UnicodeString& test, + const UnicodeString& shouldProduceStyles) +{ + UErrorCode status = U_ZERO_ERROR; + TestReplaceable *tr = new TestReplaceable(test, ""); + UnicodeString expectedStyles = shouldProduceStyles; + UnicodeString original = tr->toString(); + + Transliterator* t; + if (transliteratorName.charAt(0) == 0x2A /*'*'*/) { + UnicodeString rules(transliteratorName); + rules.remove(0,1); + UParseError pe; + t = Transliterator::createFromRules("test", rules, UTRANS_FORWARD, + pe, status); + + // test clone() + TestReplaceable *tr2 = (TestReplaceable *)tr->clone(); + if(tr2 != NULL) { + delete tr; + tr = tr2; + } + } else { + t = Transliterator::createInstance(transliteratorName, UTRANS_FORWARD, status); + } + if (U_FAILURE(status)) { + log("FAIL: failed to create the "); + log(transliteratorName); + errln(" transliterator."); + delete tr; + return; + } + t->transliterate(*tr); + UnicodeString newStyles = tr->getStyles(); + if (newStyles != expectedStyles) { + errln("FAIL Styles: " + transliteratorName + "{" + original + "} => " + + tr->toString() + "; should be {" + expectedStyles + "}!"); + } else { + log("OK: "); + log(transliteratorName); + log("("); + log(original); + log(") => "); + logln(tr->toString()); + } + delete tr; + delete t; +} + +#endif /* #if !UCONFIG_NO_TRANSLITERATION */ |