Index: icu46/source/test/intltest/reptest.cpp |
=================================================================== |
--- icu46/source/test/intltest/reptest.cpp (revision 0) |
+++ icu46/source/test/intltest/reptest.cpp (revision 0) |
@@ -0,0 +1,320 @@ |
+/******************************************************************** |
+ * COPYRIGHT: |
+ * Copyright (c) 2001-2010, 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)) { |
+ dataerrln("FAIL: failed to create the " + transliteratorName + " 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 */ |
Property changes on: icu46/source/test/intltest/reptest.cpp |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |