| /******************************************************************** |
| * COPYRIGHT: |
| * Copyright (c) 2001, 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 "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..65536) 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 defaultStyle. |
| */ |
| class TestReplaceable : public Replaceable { |
| UnicodeString chars; |
| UnicodeString styles; |
| |
| static const UChar defaultStyle; |
| |
| /** |
| * 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 { |
| s.append((UChar)(i + 0x0041)); |
| } |
| } |
| this->styles = s; |
| } |
| |
| ~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 the actual class. |
| * |
| * @draft ICU 2.2 |
| */ |
| virtual inline UClassID getDynamicClassID() const { return getStaticClassID(); } |
| |
| /** |
| * ICU "poor man's RTTI", returns a UClassID for this class. |
| * |
| * @draft ICU 2.2 |
| */ |
| static inline UClassID getStaticClassID() { return (UClassID)&fgClassID; } |
| |
| 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); |
| } |
| |
| 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()); |
| } |
| |
| |
| void fixStyles(int32_t start, int32_t limit, int32_t newLen) { |
| UChar newStyle = defaultStyle; |
| if (start != limit) { |
| newStyle = styles.charAt(start); |
| } else if (start > 0) { |
| newStyle = styles.charAt(start-1); |
| } else if (limit < styles.length() - 1) { |
| newStyle = styles.charAt(limit+1); |
| } |
| // dumb implementation for now. |
| UnicodeString s; |
| for (int i = 0; i < newLen; ++i) { |
| s.append(newStyle); |
| } |
| styles.replaceBetween(start, limit, s); |
| } |
| |
| 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::defaultStyle = 0x005F; |
| |
| void |
| ReplaceableTest::runIndexedTest(int32_t index, UBool exec, |
| const char* &name, char* /*par*/) { |
| switch (index) { |
| TESTCASE(0,TestReplaceableClass); |
| default: name = ""; break; |
| } |
| } |
| |
| |
| void ReplaceableTest::TestReplaceableClass(void) { |
| UChar rawTestArray[5][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 |
| }; |
| Check("Lower", rawTestArray[0], "1234", ""); |
| Check("Upper", rawTestArray[1], "123455", ""); // must map 00DF to SS |
| Check("Title", rawTestArray[2], "1234", ""); |
| Check("NFC", rawTestArray[3], "1234", "13"); |
| Check("NFD", rawTestArray[4], "12", "1122"); |
| } |
| |
| void ReplaceableTest::Check(const UnicodeString& transliteratorName, |
| const UnicodeString& test, |
| const UnicodeString& styles, |
| const UnicodeString& shouldProduceStyles) |
| { |
| UErrorCode status = U_ZERO_ERROR; |
| TestReplaceable *tr = new TestReplaceable(test, styles); |
| UnicodeString expectedStyles = shouldProduceStyles; |
| if (expectedStyles.length() == 0) { |
| expectedStyles = styles; |
| } |
| UnicodeString original = tr->toString(); |
| |
| Transliterator* 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; |
| } |
| |