1/* GENERATED SOURCE. DO NOT MODIFY. */ 2// © 2016 and later: Unicode, Inc. and others. 3// License & terms of use: http://www.unicode.org/copyright.html#License 4/* 5******************************************************************************* 6* Copyright (C) 2001-2012, International Business Machines 7* Corporation and others. All Rights Reserved. 8******************************************************************************* 9*/ 10 11package android.icu.dev.test.shaping; 12 13import java.lang.reflect.Method; 14import java.util.MissingResourceException; 15 16import org.junit.Test; 17 18import android.icu.dev.test.TestFmwk; 19import android.icu.text.ArabicShaping; 20import android.icu.text.ArabicShapingException; 21 22/** 23 * Regression test for Arabic shaping. 24 */ 25public class ArabicShapingRegTest extends TestFmwk { 26 27 /* constants copied from ArabicShaping for convenience */ 28 29 public static final int LENGTH_GROW_SHRINK = 0; 30 public static final int LENGTH_FIXED_SPACES_NEAR = 1; 31 public static final int LENGTH_FIXED_SPACES_AT_END = 2; 32 public static final int LENGTH_FIXED_SPACES_AT_BEGINNING = 3; 33 34 public static final int TEXT_DIRECTION_LOGICAL = 0; 35 public static final int TEXT_DIRECTION_VISUAL_LTR = 4; 36 37 public static final int LETTERS_NOOP = 0; 38 public static final int LETTERS_SHAPE = 8; 39 public static final int LETTERS_SHAPE_TASHKEEL_ISOLATED = 0x18; 40 public static final int LETTERS_UNSHAPE = 0x10; 41 42 public static final int DIGITS_NOOP = 0; 43 public static final int DIGITS_EN2AN = 0x20; 44 public static final int DIGITS_AN2EN = 0x40; 45 public static final int DIGITS_EN2AN_INIT_LR = 0x60; 46 public static final int DIGITS_EN2AN_INIT_AL = 0x80; 47// private static final int DIGITS_RESERVED = 0xa0; 48 49 public static final int DIGIT_TYPE_AN = 0; 50 public static final int DIGIT_TYPE_AN_EXTENDED = 0x100; 51 52 public static class TestData { 53 public int type; 54 public String source; 55 public int flags; 56 public String result; 57 public int length; 58 public Class error; 59 60 public static final int STANDARD = 0; 61 public static final int PREFLIGHT = 1; 62 public static final int ERROR = 2; 63 64 public static TestData standard(String source, int flags, String result) { 65 return new TestData(STANDARD, source, flags, result, 0, null); 66 } 67 68 public static TestData preflight(String source, int flags, int length) { 69 return new TestData(PREFLIGHT, source, flags, null, length, null); 70 } 71 72 public static TestData error(String source, int flags, Class error) { 73 return new TestData(ERROR, source, flags, null, 0, error); 74 } 75 76 private TestData(int type, String source, int flags, String result, int length, Class error) { 77 this.type = type; 78 this.source = source; 79 this.flags = flags; 80 this.result = result; 81 this.length = length; 82 this.error = error; 83 } 84 85 private static final String[] typenames = { "standard", "preflight", "error" }; 86 87 public String toString() { 88 StringBuffer buf = new StringBuffer(super.toString()); 89 buf.append("[\n"); 90 buf.append(typenames[type]); 91 buf.append(",\n"); 92 if (source == null) { 93 buf.append("null"); 94 } else { 95 buf.append('"'); 96 buf.append(escapedString(source)); 97 buf.append('"'); 98 } 99 buf.append(",\n"); 100 buf.append(Integer.toHexString(flags)); 101 buf.append(",\n"); 102 if (result == null) { 103 buf.append("null"); 104 } else { 105 buf.append('"'); 106 buf.append(escapedString(result)); 107 buf.append('"'); 108 } 109 buf.append(",\n"); 110 buf.append(length); 111 buf.append(",\n"); 112 buf.append(error); 113 buf.append(']'); 114 return buf.toString(); 115 } 116 } 117 118 private static final String lamAlefSpecialVLTR = 119 "\u0020\u0646\u0622\u0644\u0627\u0020" + 120 "\u0646\u0623\u064E\u0644\u0627\u0020" + 121 "\u0646\u0627\u0670\u0644\u0627\u0020" + 122 "\u0646\u0622\u0653\u0644\u0627\u0020" + 123 "\u0646\u0625\u0655\u0644\u0627\u0020" + 124 "\u0646\u0622\u0654\u0644\u0627\u0020" + 125 "\uFEFC\u0639"; 126 127 private static final String tashkeelSpecialVLTR = 128 "\u064A\u0628\u0631\u0639\u0020" + 129 "\u064A\u0628\u0651\u0631\u064E\u0639\u0020" + 130 "\u064C\u064A\u0628\u0631\u064F\u0639\u0020" + 131 "\u0628\u0670\u0631\u0670\u0639\u0020" + 132 "\u0628\u0653\u0631\u0653\u0639\u0020" + 133 "\u0628\u0654\u0631\u0654\u0639\u0020" + 134 "\u0628\u0655\u0631\u0655\u0639\u0020"; 135 136 private static final String tashkeelShaddaRTL= 137 "\u0634\u0651\u0645\u0652\u0633"; 138 private static final String tashkeelShaddaLTR= 139 "\u0633\u0652\u0645\u0651\u0634"; 140 141 private static final String ArMathSym = 142 "\uD83B\uDE00\uD83B\uDE01\uD83B\uDE02\uD83B\uDE03\u0020" + 143 "\uD83B\uDE24\uD83B\uDE05\uD83B\uDE06\u0020" + 144 "\uD83B\uDE07\uD83B\uDE08\uD83B\uDE09\u0020" + 145 "\uD83B\uDE0A\uD83B\uDE0B\uD83B\uDE0C\uD83B\uDE0D\u0020" + 146 "\uD83B\uDE0E\uD83B\uDE0F\uD83B\uDE10\uD83B\uDE11\u0020" + 147 "\uD83B\uDE12\uD83B\uDE13\uD83B\uDE14\uD83B\uDE15\u0020" + 148 "\uD83B\uDE16\uD83B\uDE17\uD83B\uDE18\u0020" + 149 "\uD83B\uDE19\uD83B\uDE1A\uD83B\uDE1B"; 150 151 private static final String ArMathSymLooped = 152 "\uD83B\uDE80\uD83B\uDE81\uD83B\uDE82\uD83B\uDE83\u0020" + 153 "\uD83B\uDE84\uD83B\uDE85\uD83B\uDE86\u0020" + 154 "\uD83B\uDE87\uD83B\uDE88\uD83B\uDE89\u0020" + 155 "\uD83B\uDE8B\uD83B\uDE8C\uD83B\uDE8D\u0020" + 156 "\uD83B\uDE8E\uD83B\uDE8F\uD83B\uDE90\uD83B\uDE91\u0020" + 157 "\uD83B\uDE92\uD83B\uDE93\uD83B\uDE94\uD83B\uDE95\u0020" + 158 "\uD83B\uDE96\uD83B\uDE97\uD83B\uDE98\u0020" + 159 "\uD83B\uDE99\uD83B\uDE9A\uD83B\uDE9B"; 160 161 private static final String ArMathSymDoubleStruck = 162 "\uD83B\uDEA1\uD83B\uDEA2\uD83B\uDEA3\u0020" + 163 "\uD83B\uDEA5\uD83B\uDEA6\u0020" + 164 "\uD83B\uDEA7\uD83B\uDEA8\uD83B\uDEA9\u0020" + 165 "\uD83B\uDEAB\uD83B\uDEAC\uD83B\uDEAD\u0020" + 166 "\uD83B\uDEAE\uD83B\uDEAF\uD83B\uDEB0\uD83B\uDEB1\u0020" + 167 "\uD83B\uDEB2\uD83B\uDEB3\uD83B\uDEB4\uD83B\uDEB5\u0020" + 168 "\uD83B\uDEB6\uD83B\uDEB7\uD83B\uDEB8\u0020" + 169 "\uD83B\uDEB9\uD83B\uDEBA\uD83B\uDEBB"; 170 171 private static final String ArMathSymInitial = 172 "\uD83B\uDE21\uD83B\uDE22\u0020" + 173 "\uD83B\uDE27\uD83B\uDE29\u0020" + 174 "\uD83B\uDE2A\uD83B\uDE2B\uD83B\uDE2C\uD83B\uDE2D\u0020" + 175 "\uD83B\uDE2E\uD83B\uDE2F\uD83B\uDE30\uD83B\uDE31\u0020" + 176 "\uD83B\uDE32\uD83B\uDE34\uD83B\uDE35\u0020" + 177 "\uD83B\uDE36\uD83B\uDE37\u0020" + 178 "\uD83B\uDE39\uD83B\uDE3B"; 179 180 private static final String ArMathSymTailed = 181 "\uD83B\uDE42\uD83B\uDE47\uD83B\uDE49\uD83B\uDE4B\u0020" + 182 "\uD83B\uDE4D\uD83B\uDE4E\uD83B\uDE4F\u0020" + 183 "\uD83B\uDE51\uD83B\uDE52\uD83B\uDE54\uD83B\uDE57\u0020" + 184 "\uD83B\uDE59\uD83B\uDE5B\uD83B\uDE5D\uD83B\uDE5F"; 185 186 private static final String ArMathSymStretched = 187 "\uD83B\uDE21\u0633\uD83B\uDE62\u0647"; 188 189 private static final String logicalUnshape = 190 "\u0020\u0020\u0020\uFE8D\uFEF5\u0020\uFEE5\u0020\uFE8D\uFEF7\u0020" + 191 "\uFED7\uFEFC\u0020\uFEE1\u0020\uFE8D\uFEDF\uFECC\uFEAE\uFE91\uFEF4" + 192 "\uFE94\u0020\uFE8D\uFEDF\uFEA4\uFEAE\uFE93\u0020\u0020\u0020\u0020"; 193 194 private static final String numSource = 195 "\u0031" + /* en:1 */ 196 "\u0627" + /* arabic:alef */ 197 "\u0032" + /* en:2 */ 198 "\u06f3" + /* an:3 */ 199 "\u0061" + /* latin:a */ 200 "\u0034"; /* en:4 */ 201 202 private static final TestData[] standardTests = { 203 /* lam alef special visual ltr */ 204 TestData.standard(lamAlefSpecialVLTR, 205 LETTERS_SHAPE | TEXT_DIRECTION_VISUAL_LTR | LENGTH_FIXED_SPACES_NEAR, 206 "\u0020\ufee5\u0020\ufef5\ufe8d\u0020" + 207 "\ufee5\u0020\ufe76\ufef7\ufe8d\u0020" + 208 "\ufee5\u0020\u0670\ufefb\ufe8d\u0020" + 209 "\ufee5\u0020\u0653\ufef5\ufe8d\u0020" + 210 "\ufee5\u0020\u0655\ufef9\ufe8d\u0020" + 211 "\ufee5\u0020\u0654\ufef5\ufe8d\u0020" + 212 "\ufefc\ufecb"), 213 TestData.standard(lamAlefSpecialVLTR, 214 LETTERS_SHAPE | TEXT_DIRECTION_VISUAL_LTR | LENGTH_FIXED_SPACES_AT_END, 215 "\u0020\ufee5\ufef5\ufe8d\u0020\ufee5" + 216 "\ufe76\ufef7\ufe8d\u0020\ufee5\u0670" + 217 "\ufefb\ufe8d\u0020\ufee5\u0653\ufef5" + 218 "\ufe8d\u0020\ufee5\u0655\ufef9\ufe8d" + 219 "\u0020\ufee5\u0654\ufef5\ufe8d\u0020" + 220 "\ufefc\ufecb\u0020\u0020\u0020\u0020" + 221 "\u0020\u0020"), 222 TestData.standard(lamAlefSpecialVLTR, 223 LETTERS_SHAPE | TEXT_DIRECTION_VISUAL_LTR | LENGTH_FIXED_SPACES_AT_BEGINNING, 224 "\u0020\u0020\u0020\u0020\u0020\u0020" + 225 "\u0020\ufee5\ufef5\ufe8d\u0020\ufee5" + 226 "\ufe76\ufef7\ufe8d\u0020\ufee5\u0670" + 227 "\ufefb\ufe8d\u0020\ufee5\u0653\ufef5" + 228 "\ufe8d\u0020\ufee5\u0655\ufef9\ufe8d" + 229 "\u0020\ufee5\u0654\ufef5\ufe8d\u0020" + 230 "\ufefc\ufecb"), 231 TestData.standard(lamAlefSpecialVLTR, 232 LETTERS_SHAPE | TEXT_DIRECTION_VISUAL_LTR | LENGTH_GROW_SHRINK, 233 "\u0020\ufee5\ufef5\ufe8d\u0020\ufee5" + 234 "\ufe76\ufef7\ufe8d\u0020\ufee5\u0670" + 235 "\ufefb\ufe8d\u0020\ufee5\u0653\ufef5" + 236 "\ufe8d\u0020\ufee5\u0655\ufef9\ufe8d" + 237 "\u0020\ufee5\u0654\ufef5\ufe8d\u0020" + 238 "\ufefc\ufecb"), 239 240 /* TASHKEEL */ 241 TestData.standard(lamAlefSpecialVLTR, 242 LETTERS_SHAPE_TASHKEEL_ISOLATED | TEXT_DIRECTION_VISUAL_LTR | LENGTH_FIXED_SPACES_NEAR, 243 "\u0020\ufee5\u0020\ufef5\ufe8d\u0020" + 244 "\ufee5\u0020\ufe76\ufef7\ufe8d\u0020" + 245 "\ufee5\u0020\u0670\ufefb\ufe8d\u0020" + 246 "\ufee5\u0020\u0653\ufef5\ufe8d\u0020" + 247 "\ufee5\u0020\u0655\ufef9\ufe8d\u0020" + 248 "\ufee5\u0020\u0654\ufef5\ufe8d\u0020" + 249 "\ufefc\ufecb"), 250 TestData.standard(lamAlefSpecialVLTR, 251 LETTERS_SHAPE_TASHKEEL_ISOLATED | TEXT_DIRECTION_VISUAL_LTR | LENGTH_FIXED_SPACES_AT_END, 252 "\u0020\ufee5\ufef5\ufe8d\u0020\ufee5" + 253 "\ufe76\ufef7\ufe8d\u0020\ufee5\u0670" + 254 "\ufefb\ufe8d\u0020\ufee5\u0653\ufef5" + 255 "\ufe8d\u0020\ufee5\u0655\ufef9\ufe8d" + 256 "\u0020\ufee5\u0654\ufef5\ufe8d\u0020" + 257 "\ufefc\ufecb\u0020\u0020\u0020\u0020" + 258 "\u0020\u0020"), 259 TestData.standard(lamAlefSpecialVLTR, 260 LETTERS_SHAPE_TASHKEEL_ISOLATED | TEXT_DIRECTION_VISUAL_LTR | LENGTH_FIXED_SPACES_AT_BEGINNING, 261 "\u0020\u0020\u0020\u0020\u0020\u0020" + 262 "\u0020\ufee5\ufef5\ufe8d\u0020\ufee5" + 263 "\ufe76\ufef7\ufe8d\u0020\ufee5\u0670" + 264 "\ufefb\ufe8d\u0020\ufee5\u0653\ufef5" + 265 "\ufe8d\u0020\ufee5\u0655\ufef9\ufe8d" + 266 "\u0020\ufee5\u0654\ufef5\ufe8d\u0020" + 267 "\ufefc\ufecb"), 268 TestData.standard(lamAlefSpecialVLTR, 269 LETTERS_SHAPE_TASHKEEL_ISOLATED | TEXT_DIRECTION_VISUAL_LTR | LENGTH_GROW_SHRINK, 270 "\u0020\ufee5\ufef5\ufe8d\u0020\ufee5" + 271 "\ufe76\ufef7\ufe8d\u0020\ufee5\u0670" + 272 "\ufefb\ufe8d\u0020\ufee5\u0653\ufef5" + 273 "\ufe8d\u0020\ufee5\u0655\ufef9\ufe8d" + 274 "\u0020\ufee5\u0654\ufef5\ufe8d\u0020" + 275 "\ufefc\ufecb"), 276 277 /* tashkeel special visual ltr */ 278 TestData.standard(tashkeelSpecialVLTR, 279 LETTERS_SHAPE | TEXT_DIRECTION_VISUAL_LTR | LENGTH_FIXED_SPACES_NEAR, 280 "\ufef2\ufe91\ufeae\ufecb\u0020" + 281 "\ufef2\ufe91\ufe7c\ufeae\ufe77\ufecb\u0020" + 282 "\ufe72\ufef2\ufe91\ufeae\ufe79\ufecb\u0020" + 283 "\ufe8f\u0670\ufeae\u0670\ufecb\u0020" + 284 "\ufe8f\u0653\ufeae\u0653\ufecb\u0020" + 285 "\ufe8f\u0654\ufeae\u0654\ufecb\u0020" + 286 "\ufe8f\u0655\ufeae\u0655\ufecb\u0020"), 287 288 TestData.standard(tashkeelSpecialVLTR, 289 LETTERS_SHAPE_TASHKEEL_ISOLATED | TEXT_DIRECTION_VISUAL_LTR | LENGTH_FIXED_SPACES_NEAR, 290 "\ufef2\ufe91\ufeae\ufecb\u0020" + 291 "\ufef2\ufe91\ufe7c\ufeae\ufe76\ufecb\u0020" + 292 "\ufe72\ufef2\ufe91\ufeae\ufe78\ufecb\u0020" + 293 "\ufe8f\u0670\ufeae\u0670\ufecb\u0020" + 294 "\ufe8f\u0653\ufeae\u0653\ufecb\u0020" + 295 "\ufe8f\u0654\ufeae\u0654\ufecb\u0020" + 296 "\ufe8f\u0655\ufeae\u0655\ufecb\u0020"), 297 298 TestData.standard(tashkeelShaddaRTL, 299 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_BEGIN |ArabicShaping.TEXT_DIRECTION_VISUAL_RTL , 300 "\u0020\ufeb7\ufe7d\ufee4\ufeb2"), 301 TestData.standard(tashkeelShaddaRTL, 302 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_END|ArabicShaping.TEXT_DIRECTION_VISUAL_RTL , 303 "\ufeb7\ufe7d\ufee4\ufeb2\u0020"), 304 TestData.standard(tashkeelShaddaRTL, 305 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_RESIZE|ArabicShaping.TEXT_DIRECTION_VISUAL_RTL , 306 "\ufeb7\ufe7d\ufee4\ufeb2"), 307 TestData.standard(tashkeelShaddaRTL, 308 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_REPLACE_BY_TATWEEL|ArabicShaping.TEXT_DIRECTION_VISUAL_RTL , 309 "\ufeb7\ufe7d\ufee4\u0640\ufeb2"), 310 311 TestData.standard(tashkeelShaddaLTR, 312 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_BEGIN |ArabicShaping.TEXT_DIRECTION_VISUAL_LTR , 313 "\u0020\ufeb2\ufee4\ufe7d\ufeb7"), 314 TestData.standard(tashkeelShaddaLTR, 315 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_END |ArabicShaping.TEXT_DIRECTION_VISUAL_LTR , 316 "\ufeb2\ufee4\ufe7d\ufeb7\u0020"), 317 TestData.standard(tashkeelShaddaLTR, 318 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_RESIZE |ArabicShaping.TEXT_DIRECTION_VISUAL_LTR , 319 "\ufeb2\ufee4\ufe7d\ufeb7"), 320 TestData.standard(tashkeelShaddaLTR, 321 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_REPLACE_BY_TATWEEL |ArabicShaping.TEXT_DIRECTION_VISUAL_LTR , 322 "\ufeb2\u0640\ufee4\ufe7d\ufeb7"), 323 324 TestData.standard(ArMathSym, 325 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_BEGIN |ArabicShaping.TEXT_DIRECTION_VISUAL_RTL , 326 "\uD83B\uDE00\uD83B\uDE01\uD83B\uDE02\uD83B\uDE03\u0020" + 327 "\uD83B\uDE24\uD83B\uDE05\uD83B\uDE06\u0020" + 328 "\uD83B\uDE07\uD83B\uDE08\uD83B\uDE09\u0020" + 329 "\uD83B\uDE0A\uD83B\uDE0B\uD83B\uDE0C\uD83B\uDE0D\u0020" + 330 "\uD83B\uDE0E\uD83B\uDE0F\uD83B\uDE10\uD83B\uDE11\u0020" + 331 "\uD83B\uDE12\uD83B\uDE13\uD83B\uDE14\uD83B\uDE15\u0020" + 332 "\uD83B\uDE16\uD83B\uDE17\uD83B\uDE18\u0020" + 333 "\uD83B\uDE19\uD83B\uDE1A\uD83B\uDE1B"), 334 TestData.standard(ArMathSymLooped, 335 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_END|ArabicShaping.TEXT_DIRECTION_VISUAL_RTL , 336 "\uD83B\uDE80\uD83B\uDE81\uD83B\uDE82\uD83B\uDE83\u0020" + 337 "\uD83B\uDE84\uD83B\uDE85\uD83B\uDE86\u0020" + 338 "\uD83B\uDE87\uD83B\uDE88\uD83B\uDE89\u0020" + 339 "\uD83B\uDE8B\uD83B\uDE8C\uD83B\uDE8D\u0020" + 340 "\uD83B\uDE8E\uD83B\uDE8F\uD83B\uDE90\uD83B\uDE91\u0020" + 341 "\uD83B\uDE92\uD83B\uDE93\uD83B\uDE94\uD83B\uDE95\u0020" + 342 "\uD83B\uDE96\uD83B\uDE97\uD83B\uDE98\u0020" + 343 "\uD83B\uDE99\uD83B\uDE9A\uD83B\uDE9B"), 344 TestData.standard(ArMathSymDoubleStruck, 345 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_RESIZE|ArabicShaping.TEXT_DIRECTION_VISUAL_RTL , 346 "\uD83B\uDEA1\uD83B\uDEA2\uD83B\uDEA3\u0020" + 347 "\uD83B\uDEA5\uD83B\uDEA6\u0020" + 348 "\uD83B\uDEA7\uD83B\uDEA8\uD83B\uDEA9\u0020" + 349 "\uD83B\uDEAB\uD83B\uDEAC\uD83B\uDEAD\u0020" + 350 "\uD83B\uDEAE\uD83B\uDEAF\uD83B\uDEB0\uD83B\uDEB1\u0020" + 351 "\uD83B\uDEB2\uD83B\uDEB3\uD83B\uDEB4\uD83B\uDEB5\u0020" + 352 "\uD83B\uDEB6\uD83B\uDEB7\uD83B\uDEB8\u0020" + 353 "\uD83B\uDEB9\uD83B\uDEBA\uD83B\uDEBB"), 354 355 TestData.standard(ArMathSymInitial, 356 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_BEGIN |ArabicShaping.TEXT_DIRECTION_VISUAL_LTR , 357 "\uD83B\uDE21\uD83B\uDE22\u0020" + 358 "\uD83B\uDE27\uD83B\uDE29\u0020" + 359 "\uD83B\uDE2A\uD83B\uDE2B\uD83B\uDE2C\uD83B\uDE2D\u0020" + 360 "\uD83B\uDE2E\uD83B\uDE2F\uD83B\uDE30\uD83B\uDE31\u0020" + 361 "\uD83B\uDE32\uD83B\uDE34\uD83B\uDE35\u0020" + 362 "\uD83B\uDE36\uD83B\uDE37\u0020" + 363 "\uD83B\uDE39\uD83B\uDE3B"), 364 TestData.standard(ArMathSymTailed, 365 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_END |ArabicShaping.TEXT_DIRECTION_VISUAL_LTR , 366 "\uD83B\uDE42\uD83B\uDE47\uD83B\uDE49\uD83B\uDE4B\u0020" + 367 "\uD83B\uDE4D\uD83B\uDE4E\uD83B\uDE4F\u0020" + 368 "\uD83B\uDE51\uD83B\uDE52\uD83B\uDE54\uD83B\uDE57\u0020" + 369 "\uD83B\uDE59\uD83B\uDE5B\uD83B\uDE5D\uD83B\uDE5F"), 370 TestData.standard(ArMathSymStretched, 371 ArabicShaping.LETTERS_SHAPE|ArabicShaping.TASHKEEL_RESIZE |ArabicShaping.TEXT_DIRECTION_VISUAL_LTR , 372 "\uD83B\uDE21\uFEB1\uD83B\uDE62\uFEE9"), 373 374 /* logical unshape */ 375 TestData.standard(logicalUnshape, 376 LETTERS_UNSHAPE | TEXT_DIRECTION_LOGICAL | LENGTH_FIXED_SPACES_NEAR, 377 "\u0020\u0020\u0020\u0627\u0644\u0622\u0646\u0020\u0627\u0644\u0623\u0642\u0644\u0627" + 378 "\u0645\u0020\u0627\u0644\u0639\u0631\u0628\u064a\u0629\u0020\u0627\u0644\u062d\u0631" + 379 "\u0629\u0020\u0020\u0020\u0020"), 380 TestData.standard(logicalUnshape, 381 LETTERS_UNSHAPE | TEXT_DIRECTION_LOGICAL | LENGTH_FIXED_SPACES_AT_END, 382 "\u0020\u0020\u0020\u0627\u0644\u0622\u0020\u0646\u0020\u0627\u0644\u0623\u0020\u0642" + 383 "\u0644\u0627\u0020\u0645\u0020\u0627\u0644\u0639\u0631\u0628\u064a\u0629\u0020\u0627" + 384 "\u0644\u062d\u0631\u0629\u0020"), 385 TestData.standard(logicalUnshape, 386 LETTERS_UNSHAPE | TEXT_DIRECTION_LOGICAL | LENGTH_FIXED_SPACES_AT_BEGINNING, 387 "\u0627\u0644\u0622\u0020\u0646\u0020\u0627\u0644\u0623\u0020\u0642\u0644\u0627\u0020" + 388 "\u0645\u0020\u0627\u0644\u0639\u0631\u0628\u064a\u0629\u0020\u0627\u0644\u062d\u0631" + 389 "\u0629\u0020\u0020\u0020\u0020"), 390 TestData.standard(logicalUnshape, 391 LETTERS_UNSHAPE | TEXT_DIRECTION_LOGICAL | LENGTH_GROW_SHRINK, 392 "\u0020\u0020\u0020\u0627\u0644\u0622\u0020\u0646\u0020\u0627\u0644\u0623\u0020\u0642" + 393 "\u0644\u0627\u0020\u0645\u0020\u0627\u0644\u0639\u0631\u0628\u064a\u0629\u0020\u0627" + 394 "\u0644\u062d\u0631\u0629\u0020\u0020\u0020\u0020"), 395 396 /* numbers */ 397 TestData.standard(numSource, 398 DIGITS_EN2AN | DIGIT_TYPE_AN, 399 "\u0661\u0627\u0662\u06f3\u0061\u0664"), 400 TestData.standard(numSource, 401 DIGITS_AN2EN | DIGIT_TYPE_AN_EXTENDED, 402 "\u0031\u0627\u0032\u0033\u0061\u0034"), 403 TestData.standard(numSource, 404 DIGITS_EN2AN_INIT_LR | DIGIT_TYPE_AN, 405 "\u0031\u0627\u0662\u06f3\u0061\u0034"), 406 TestData.standard(numSource, 407 DIGITS_EN2AN_INIT_AL | DIGIT_TYPE_AN_EXTENDED, 408 "\u06f1\u0627\u06f2\u06f3\u0061\u0034"), 409 TestData.standard(numSource, 410 DIGITS_EN2AN_INIT_LR | DIGIT_TYPE_AN | TEXT_DIRECTION_VISUAL_LTR, 411 "\u0661\u0627\u0032\u06f3\u0061\u0034"), 412 TestData.standard(numSource, 413 DIGITS_EN2AN_INIT_AL | DIGIT_TYPE_AN_EXTENDED | TEXT_DIRECTION_VISUAL_LTR, 414 "\u06f1\u0627\u0032\u06f3\u0061\u06f4"), 415 416 /* no-op */ 417 TestData.standard(numSource, 418 0, 419 numSource), 420 }; 421 422 private static final TestData[] preflightTests = { 423 /* preflight */ 424 TestData.preflight("\u0644\u0627", 425 LETTERS_SHAPE | LENGTH_GROW_SHRINK, 426 1), 427 428 TestData.preflight("\u0644\u0627\u0031", 429 DIGITS_EN2AN | DIGIT_TYPE_AN_EXTENDED | LENGTH_GROW_SHRINK, 430 3), 431 432 TestData.preflight("\u0644\u0644", 433 LETTERS_SHAPE | LENGTH_GROW_SHRINK, 434 2), 435 436 TestData.preflight("\ufef7", 437 LETTERS_UNSHAPE | LENGTH_GROW_SHRINK, 438 2), 439 }; 440 441 private static final TestData[] errorTests = { 442 /* bad data */ 443 TestData.error("\u0020\ufef7\u0644\u0020", 444 LETTERS_UNSHAPE | LENGTH_FIXED_SPACES_NEAR, 445 ArabicShapingException.class), 446 447 TestData.error("\u0020\ufef7", 448 LETTERS_UNSHAPE | LENGTH_FIXED_SPACES_AT_END, 449 ArabicShapingException.class), 450 451 TestData.error("\ufef7\u0020", 452 LETTERS_UNSHAPE | LENGTH_FIXED_SPACES_AT_BEGINNING, 453 ArabicShapingException.class), 454 455 /* bad options */ 456 TestData.error("\ufef7", 457 0xffffffff, 458 IllegalArgumentException.class), 459 460 TestData.error("\ufef7", 461 LETTERS_UNSHAPE | LENGTH_GROW_SHRINK, 462 ArabicShapingException.class), 463 464 TestData.error(null, 465 LETTERS_UNSHAPE | LENGTH_FIXED_SPACES_AT_END, 466 IllegalArgumentException.class), 467 }; 468 469 @Test 470 public void TestStandard() { 471 for (int i = 0; i < standardTests.length; ++i) { 472 TestData test = standardTests[i]; 473 474 Exception ex = null; 475 String result = null; 476 ArabicShaping shaper = null; 477 478 try { 479 shaper = new ArabicShaping(test.flags); 480 result = shaper.shape(test.source); 481 } 482 catch(MissingResourceException e){ 483 throw e; 484 } 485 catch (IllegalStateException ie){ 486 warnln("IllegalStateException: "+ie.toString()); 487 return; 488 } 489 catch (Exception e) { 490 ex = e; 491 } 492 493 if (!test.result.equals(result)) { 494 reportTestFailure(i, test, shaper, result, ex); 495 } 496 } 497 } 498 499 @Test 500 public void TestPreflight() { 501 for (int i = 0; i < preflightTests.length; ++i) { 502 TestData test = preflightTests[i]; 503 504 Exception ex = null; 505 char src[] = null; 506 int len = 0; 507 ArabicShaping shaper = null; 508 509 if (test.source != null) { 510 src = test.source.toCharArray(); 511 } 512 513 try { 514 shaper = new ArabicShaping(test.flags); 515 len = shaper.shape(src, 0, src.length, null, 0, 0); 516 } 517 catch (Exception e) { 518 ex = e; 519 } 520 521 if (test.length != len) { 522 reportTestFailure(i, test, shaper, test.source, ex); 523 } 524 } 525 } 526 527 @Test 528 public void TestError() { 529 for (int i = 0; i < errorTests.length; ++i) { 530 TestData test = errorTests[i]; 531 532 Exception ex = null; 533 char src[] = null; 534 int len = 0; 535 ArabicShaping shaper = null; 536 537 if (test.source != null) { 538 src = test.source.toCharArray(); 539 len = src.length; 540 } 541 542 try { 543 shaper = new ArabicShaping(test.flags); 544 shaper.shape(src, 0, len); 545 } 546 catch (Exception e) { 547 ex = e; 548 } 549 550 if (!test.error.isInstance(ex)) { 551 reportTestFailure(i, test, shaper, test.source, ex); 552 } 553 } 554 } 555 556 @Test 557 public void TestEquals() 558 { 559 ArabicShaping as1 = new ArabicShaping(LETTERS_SHAPE | TEXT_DIRECTION_VISUAL_LTR | LENGTH_FIXED_SPACES_NEAR); 560 ArabicShaping as2 = new ArabicShaping(LETTERS_SHAPE | TEXT_DIRECTION_VISUAL_LTR | LENGTH_FIXED_SPACES_NEAR); 561 ArabicShaping as3 = new ArabicShaping(LETTERS_UNSHAPE | TEXT_DIRECTION_LOGICAL | LENGTH_FIXED_SPACES_AT_BEGINNING); 562 563 if (! as1.equals(as1)) { 564 err("as1: " + as1 + " does not equal itself!\n"); 565 } 566 567 if (! as1.equals(as2)) { 568 err("as1: " + as1 + ", as2: " + as2 + " are not equal, but should be.\n"); 569 } 570 571 if (as1.equals(as3)) { 572 err("as1: " + as1 + ", as3: " + as3 + " are equal but should not be.\n"); 573 } 574 } 575 576 // TODO(junit): remove this and convert callers to parameterized tests 577 private void reportTestFailure(int index, TestData test, ArabicShaping shaper, String result, Exception error) { 578 if (error != null && error instanceof MissingResourceException ) { 579 warnln(error.getMessage()); 580 } 581 582 StringBuffer buf = new StringBuffer(); 583 buf.append("*** test failure ***\n"); 584 buf.append("index: " + index + "\n"); 585 buf.append("test: " + test + "\n"); 586 buf.append("shaper: " + shaper + "\n"); 587 buf.append("result: " + escapedString(result) + "\n"); 588 buf.append("error: " + error + "\n"); 589 590 if (result != null && test.result != null && !test.result.equals(result)) { 591 for (int i = 0; i < Math.max(test.result.length(), result.length()); ++i) { 592 String temp = Integer.toString(i); 593 if (temp.length() < 2) { 594 temp = " ".concat(temp); 595 } 596 char trg = i < test.result.length() ? test.result.charAt(i) : '\uffff'; 597 char res = i < result.length() ? result.charAt(i) : '\uffff'; 598 599 buf.append("[" + temp + "] "); 600 buf.append(escapedString("" + trg) + " "); 601 buf.append(escapedString("" + res) + " "); 602 if (trg != res) { 603 buf.append("***"); 604 } 605 buf.append("\n"); 606 } 607 } 608 err(buf.toString()); 609 } 610 611 private static String escapedString(String str) { 612 if (str == null) { 613 return null; 614 } 615 616 StringBuffer buf = new StringBuffer(str.length() * 6); 617 for (int i = 0; i < str.length(); ++i) { 618 char ch = str.charAt(i); 619 buf.append("\\u"); 620 if (ch < 0x1000) { 621 buf.append('0'); 622 } 623 if (ch < 0x0100) { 624 buf.append('0'); 625 } 626 if (ch < 0x0010) { 627 buf.append('0'); 628 } 629 buf.append(Integer.toHexString(ch)); 630 } 631 return buf.toString(); 632 } 633 634 /* Tests the method 635 * public int shape(char[] source, int sourceStart, int sourceLength, 636 * char[] dest, int destStart, int destSize) throws ArabicShapingException) 637 */ 638 @Test 639 public void TestShape(){ 640 // Tests when 641 // if (sourceStart < 0 || sourceLength < 0 || sourceStart + sourceLength > source.length) 642 // Is true 643 ArabicShaping as = new ArabicShaping(0); 644 char[] source = {'d','u','m','m','y'}; 645 char[] dest = {'d','u','m','m','y'}; 646 int[] negNum = {-1,-2,-5,-10,-100}; 647 648 649 for(int i=0; i<negNum.length; i++){ 650 try{ 651 // Checks when "sourceStart < 0" 652 as.shape(source, negNum[i], 0, dest, 0, 0); 653 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 654 "suppose to return an exception when 'sourceStart < 0'."); 655 } catch(Exception e){} 656 657 try{ 658 // Checks when "sourceLength < 0" 659 as.shape(source, 0, negNum[i], dest, 0, 0); 660 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 661 "suppose to return an exception when 'sourceLength < 0'."); 662 } catch(Exception e){} 663 } 664 665 // Checks when "sourceStart + sourceLength > source.length" 666 try{ 667 as.shape(source, 3, 3, dest, 0, 0); 668 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 669 "suppose to return an exception when 'sourceStart + sourceLength > source.length'."); 670 } catch(Exception e){} 671 try{ 672 as.shape(source, 2, 4, dest, 0, 0); 673 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 674 "suppose to return an exception when 'sourceStart + sourceLength > source.length'."); 675 } catch(Exception e){} 676 try{ 677 as.shape(source, 1, 5, dest, 0, 0); 678 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 679 "suppose to return an exception when 'sourceStart + sourceLength > source.length'."); 680 } catch(Exception e){} 681 try{ 682 as.shape(source, 0, 6, dest, 0, 0); 683 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 684 "suppose to return an exception when 'sourceStart + sourceLength > source.length'."); 685 } catch(Exception e){} 686 687 // Checks when "if (dest == null && destSize != 0)" is true 688 try{ 689 as.shape(source, 2, 2, null, 0, 1); 690 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 691 "suppose to return an exception when 'dest == null && destSize != 0'."); 692 } catch(Exception e){} 693 694 // Checks when 695 // if ((destSize != 0) && (destStart < 0 || destSize < 0 || destStart + destSize > dest.length)) 696 for(int i=0; i<negNum.length; i++){ 697 try{ 698 as.shape(source, 2, 2, dest, negNum[i], 1); 699 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 700 "suppose to return an exception when " + 701 "(destSize != 0) && (destStart < 0 || destSize < 0 || destStart + destSize > dest.length)."); 702 } catch(Exception e){} 703 704 try{ 705 as.shape(source, 2, 2, dest, 0, negNum[i]); 706 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 707 "suppose to return an exception when " + 708 "(destSize != 0) && (destStart < 0 || destSize < 0 || destStart + destSize > dest.length)."); 709 } catch(Exception e){} 710 } 711 712 // Checks when "destStart + destSize > dest.length" 713 try{ 714 as.shape(source, 2, 2, dest, 3, 3); 715 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 716 "suppose to return an exception when " + 717 "(destSize != 0) && (destStart < 0 || destSize < 0 || destStart + destSize > dest.length)."); 718 } catch(Exception e){} 719 try{ 720 as.shape(source, 2, 2, dest, 2, 4); 721 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 722 "suppose to return an exception when " + 723 "(destSize != 0) && (destStart < 0 || destSize < 0 || destStart + destSize > dest.length)."); 724 } catch(Exception e){} 725 try{ 726 as.shape(source, 2, 2, dest, 1, 5); 727 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 728 "suppose to return an exception when " + 729 "(destSize != 0) && (destStart < 0 || destSize < 0 || destStart + destSize > dest.length)."); 730 } catch(Exception e){} 731 try{ 732 as.shape(source, 2, 2, dest, 0, 6); 733 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 734 "suppose to return an exception when " + 735 "(destSize != 0) && (destStart < 0 || destSize < 0 || destStart + destSize > dest.length)."); 736 } catch(Exception e){} 737 738 // Tests when "throw new IllegalArgumentException("Wrong Tashkeel argument")" 739 int[] invalid_Tashkeel = {-1000, -500, -100}; 740 for(int i=0; i < invalid_Tashkeel.length; i++){ 741 ArabicShaping arabicShape = new ArabicShaping(invalid_Tashkeel[i]); 742 try { 743 arabicShape.shape(source,0,0,dest,0,1); 744 errln("ArabicShaping.shape(char[],int,int,char[],int,int) was " + 745 "suppose to return an exception for 'Wrong Tashkeel argument' for " + 746 "an option value of " + invalid_Tashkeel[i]); 747 } catch (Exception e) {} 748 } 749 } 750 751 @Test 752 public void TestCoverage() { 753 ArabicShaping shp = new ArabicShaping(LETTERS_SHAPE | TEXT_DIRECTION_VISUAL_LTR | LENGTH_FIXED_SPACES_NEAR); 754 755 // Test ArabicShaping#toString(); 756 assertEquals("ArabicShaping#toString() failed.", 757 shp.toString(), 758 "android.icu.text.ArabicShaping@d[LamAlef spaces at near, visual, shape letters," + 759 " no digit shaping, standard Arabic-Indic digits]"); 760 761 // Test ArabicShaping#hashCode() 762 assertEquals("ArabicShaping#hashCode() failed.", shp.hashCode(), 13); 763 } 764 765 private boolean getStaticCharacterHelperFunctionValue(String methodName, char testValue) throws Exception { 766 Method m = ArabicShaping.class.getDeclaredMethod(methodName, Character.TYPE); 767 m.setAccessible(true); 768 Object returnValue = m.invoke(null, testValue); 769 770 if (Integer.class.isInstance(returnValue)) { 771 return (Integer)returnValue == 1; 772 } 773 return (Boolean)returnValue; 774 } 775 776 @Test 777 public void TestHelperFunctions() throws Exception { 778 // Test private static helper functions that are used internally: 779 780 // ArabicShaping.isSeenTailFamilyChar(char) 781 assertTrue("ArabicShaping.isSeenTailFamilyChar(char) failed.", 782 getStaticCharacterHelperFunctionValue("isSeenTailFamilyChar", (char)0xfeb1)); 783 784 // ArabicShaping.isAlefMaksouraChar(char) 785 assertTrue("ArabicShaping.isAlefMaksouraChar(char) failed.", 786 getStaticCharacterHelperFunctionValue("isAlefMaksouraChar", (char)0xfeef)); 787 788 // ArabicShaping.isTailChar(char) 789 assertTrue("ArabicShaping.isTailChar(char) failed.", 790 getStaticCharacterHelperFunctionValue("isTailChar", (char)0x200B)); 791 792 // ArabicShaping.isYehHamzaChar(char) 793 assertTrue("ArabicShaping.isYehHamzaChar(char) failed.", 794 getStaticCharacterHelperFunctionValue("isYehHamzaChar", (char)0xfe89)); 795 796 } 797} 798 799