2 *******************************************************************************
3 * Copyright (C) 2001-2010, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
7 package com.ibm.icu.dev.test.translit;
9 import com.ibm.icu.dev.test.TestFmwk;
10 import com.ibm.icu.impl.Utility;
11 import com.ibm.icu.text.Replaceable;
12 import com.ibm.icu.text.ReplaceableString;
13 import com.ibm.icu.text.Transliterator;
17 * @summary Round trip test of Transliterator
19 public class ReplaceableTest extends TestFmwk {
21 public static void main(String[] args) throws Exception {
22 new ReplaceableTest().run(args);
26 check("Lower", "ABCD", "1234");
27 check("Upper", "abcd\u00DF", "123455"); // must map 00DF to SS
28 check("Title", "aBCD", "1234");
29 check("NFC", "A\u0300E\u0300", "13");
30 check("NFD", "\u00C0\u00C8", "1122");
31 check("*(x) > A $1 B", "wxy", "11223");
32 check("*(x)(y) > A $2 B $1 C $2 D", "wxyz", "113322334");
33 check("*(x)(y)(z) > A $3 B $2 C $1 D", "wxyzu", "114433225");
34 // TODO Revisit the following in 2.6 or later.
35 check("*x > a", "xyz", "223"); // expect "123"?
36 check("*x > a", "wxy", "113"); // expect "123"?
37 check("*x > a", "\uFFFFxy", "_33"); // expect "_23"?
38 check("*(x) > A $1 B", "\uFFFFxy", "__223");
41 void check(String transliteratorName, String test, String shouldProduceStyles) {
42 TestReplaceable tr = new TestReplaceable(test, null);
43 String original = tr.toString();
46 if (transliteratorName.startsWith("*")) {
47 transliteratorName = transliteratorName.substring(1);
48 t = Transliterator.createFromRules("test", transliteratorName,
49 Transliterator.FORWARD);
51 t = Transliterator.getInstance(transliteratorName);
54 String newStyles = tr.getStyles();
55 if (!newStyles.equals(shouldProduceStyles)) {
56 errln("FAIL Styles: " + transliteratorName + " ( "
57 + original + " ) => " + tr.toString() + "; should be {" + shouldProduceStyles + "}!");
59 logln("OK: " + transliteratorName + " ( " + original + " ) => " + tr.toString());
62 if (!tr.hasMetaData() || tr.chars.hasMetaData()
63 || tr.styles.hasMetaData()) {
64 errln("Fail hasMetaData()");
70 * This is a test class that simulates styled text.
71 * It associates a style number (0..65535) with each character,
72 * and maintains that style in the normal fashion:
73 * When setting text from raw string or characters,<br>
74 * Set the styles to the style of the first character replaced.<br>
75 * If no characters are replaced, use the style of the previous character.<br>
76 * If at start, use the following character<br>
77 * Otherwise use NO_STYLE.
79 static class TestReplaceable implements Replaceable {
80 ReplaceableString chars;
81 ReplaceableString styles;
83 static final char NO_STYLE = '_';
85 static final char NO_STYLE_MARK = 0xFFFF;
87 TestReplaceable (String text, String styles) {
88 chars = new ReplaceableString(text);
89 StringBuffer s = new StringBuffer();
90 for (int i = 0; i < text.length(); ++i) {
91 if (styles != null && i < styles.length()) {
92 s.append(styles.charAt(i));
94 if (text.charAt(i) == NO_STYLE_MARK) {
97 s.append((char) (i + '1'));
101 this.styles = new ReplaceableString(s.toString());
104 public String getStyles() {
105 return styles.toString();
108 public String toString() {
109 return chars.toString() + "{" + styles.toString() + "}";
112 public String substring(int start, int limit) {
113 return chars.substring(start, limit);
116 public int length() {
117 return chars.length();
120 public char charAt(int offset) {
121 return chars.charAt(offset);
124 public int char32At(int offset) {
125 return chars.char32At(offset);
128 public void getChars(int srcStart, int srcLimit, char dst[], int dstStart) {
129 chars.getChars(srcStart, srcLimit, dst, dstStart);
132 public void replace(int start, int limit, String text) {
133 if (substring(start,limit).equals(text)) return; // NO ACTION!
134 if (DEBUG) System.out.print(Utility.escape(toString() + " -> replace(" + start +
135 "," + limit + "," + text) + ") -> ");
136 chars.replace(start, limit, text);
137 fixStyles(start, limit, text.length());
138 if (DEBUG) System.out.println(Utility.escape(toString()));
141 public void replace(int start, int limit, char[] charArray,
142 int charsStart, int charsLen) {
143 if (substring(start,limit).equals(new String(charArray, charsStart, charsLen-charsStart))) return; // NO ACTION!
144 this.chars.replace(start, limit, charArray, charsStart, charsLen);
145 fixStyles(start, limit, charsLen);
148 void fixStyles(int start, int limit, int newLen) {
149 char newStyle = NO_STYLE;
150 if (start != limit && styles.charAt(start) != NO_STYLE) {
151 newStyle = styles.charAt(start);
152 } else if (start > 0 && charAt(start-1) != NO_STYLE_MARK) {
153 newStyle = styles.charAt(start-1);
154 } else if (limit < styles.length()) {
155 newStyle = styles.charAt(limit);
157 // dumb implementation for now.
158 StringBuffer s = new StringBuffer();
159 for (int i = 0; i < newLen; ++i) {
160 // this doesn't really handle an embedded NO_STYLE_MARK
161 // in the middle of a long run of characters right -- but
162 // that case shouldn't happen anyway
163 if (charAt(start+i) == NO_STYLE_MARK) {
169 styles.replace(start, limit, s.toString());
172 public void copy(int start, int limit, int dest) {
173 chars.copy(start, limit, dest);
174 styles.copy(start, limit, dest);
177 public boolean hasMetaData() {
181 static final boolean DEBUG = false;
184 public void Test5789() {
186 "IETR > IET | \\' R; # (1) do split ietr between t and r\r\n" +
187 "I[EH] > I; # (2) friedrich";
188 Transliterator trans = Transliterator.createFromRules("foo", rules, Transliterator.FORWARD);
189 String result = trans.transliterate("BLENKDIETRICH");
190 assertEquals("Rule breakage", "BLENKDIET'RICH", result);