1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package ifc.i18n; 25 26 import java.util.Vector; 27 28 import lib.MultiMethodTest; 29 import lib.Status; 30 import lib.StatusException; 31 32 import com.sun.star.i18n.Boundary; 33 import com.sun.star.i18n.LineBreakHyphenationOptions; 34 import com.sun.star.i18n.LineBreakResults; 35 import com.sun.star.i18n.LineBreakUserOptions; 36 import com.sun.star.i18n.ScriptType; 37 import com.sun.star.i18n.WordType; 38 import com.sun.star.i18n.XBreakIterator; 39 import com.sun.star.lang.Locale; 40 41 /** 42 * Testing <code>com.sun.star.i18n.XBreakIterator</code> 43 * interface methods : 44 * <ul> 45 * <li><code> nextCharacters()</code></li> 46 * <li><code> previousCharacters()</code></li> 47 * <li><code> nextWord()</code></li> 48 * <li><code> previousWord()</code></li> 49 * <li><code> getWordBoundary()</code></li> 50 * <li><code> getWordType()</code></li> 51 * <li><code> isBeginWord()</code></li> 52 * <li><code> isEndWord()</code></li> 53 * <li><code> beginOfSentence()</code></li> 54 * <li><code> endOfSentence()</code></li> 55 * <li><code> getLineBreak()</code></li> 56 * <li><code> beginOfScript()</code></li> 57 * <li><code> endOfScript()</code></li> 58 * <li><code> nextScript()</code></li> 59 * <li><code> previousScript()</code></li> 60 * <li><code> getScriptType()</code></li> 61 * <li><code> beginOfCharBlock()</code></li> 62 * <li><code> endOfCharBlock()</code></li> 63 * <li><code> nextCharBlock()</code></li> 64 * <li><code> previousCharBlock()</code></li> 65 * </ul> <p> 66 * This test needs the following object relations : 67 * <ul> 68 * <li> <code>'Locale'</code> 69 * (of type <code>com.sun.star.lang.Locale</code>): 70 * this locale is used as locale argument for tested methods. 71 * </li> 72 * <li> <code>'UnicodeString'</code> 73 * (of type <code>String</code>): Unicode string which is passed 74 * to methods except 'CharacterBlock' methods. 75 * </li> 76 * <ul> <p> 77 * @see com.sun.star.i18n.XBreakIterator 78 */ 79 public class _XBreakIterator extends MultiMethodTest { 80 81 public XBreakIterator oObj = null; 82 83 Locale locale = null; 84 String UnicodeString = null; 85 86 short wordType = WordType.ANYWORD_IGNOREWHITESPACES; 87 88 /** 89 * Retrieves object relations. 90 * @throws StatusException If one of relations not found. 91 */ before()92 protected void before() { 93 locale = (Locale)tEnv.getObjRelation("Locale"); 94 if (locale == null) { 95 throw new StatusException 96 (Status.failed("Relation 'Locale' not found")) ; 97 } 98 99 UnicodeString = (String)tEnv.getObjRelation("UnicodeString"); 100 if (UnicodeString == null) { 101 throw new StatusException(Status.failed 102 ("Relation 'UnicodeString' not found")) ; 103 } 104 } 105 106 /** 107 * Compares returned next character positions with expected values. <p> 108 * 109 * Has <b>OK</b> status if position after travel and traveled length 110 * has expected values. 111 */ _nextCharacters()112 public void _nextCharacters() { 113 short nCharacterIteratorMode = 114 com.sun.star.i18n.CharacterIteratorMode.SKIPCHARACTER; 115 116 int strLength = UnicodeString.length(); 117 118 //Start from position : Travel ... chars : 119 // Actual position after : How many chars traveled 120 int[][] nextCharacters = { 121 { 1, 5000, strLength , strLength - 1 }, 122 { 10, 6, 16, 6}}; 123 124 boolean bRes = true; 125 126 for(int i = 0; i < nextCharacters.length; i++) { 127 int[] lDone = new int[1]; 128 long lRes = oObj.nextCharacters(UnicodeString, nextCharacters[i][0], 129 locale, nCharacterIteratorMode, nextCharacters[i][1], lDone); 130 log.println("Expected result is: lRes = " + nextCharacters[i][2] + 131 "; lDone = " + nextCharacters[i][3] ); 132 log.println("Actual result is: lRes = " + lRes + 133 "; lDone = " + lDone[0] ); 134 135 bRes = bRes && lRes == nextCharacters[i][2]; 136 bRes = bRes && lDone[0] == nextCharacters[i][3]; 137 } 138 139 tRes.tested("nextCharacters()", bRes); 140 } 141 142 /** 143 * Compares returned previous character positions with expected values. <p> 144 * 145 * Has <b>OK</b> status if position after travel and traveled length 146 * has expected values. 147 */ _previousCharacters()148 public void _previousCharacters() { 149 short nCharacterIteratorMode = 150 com.sun.star.i18n.CharacterIteratorMode.SKIPCHARACTER; 151 152 153 //Start from position : Travel ... chars : Actual position after : 154 //How many chars traveled 155 int[][] previousCharacters = { 156 {5, 5000, 0, 5}, 157 {10, 6, 4, 6}}; 158 159 boolean bRes = true; 160 for(int i = 0; i < previousCharacters.length; i++) { 161 int[] lDone = new int[1]; 162 int lRes = oObj.previousCharacters(UnicodeString, 163 previousCharacters[i][0], 164 locale, nCharacterIteratorMode, 165 previousCharacters[i][1], lDone); 166 log.println("Expected result is: lRes = " + previousCharacters[i][2] 167 + "; lDone = " + previousCharacters[i][3] ); 168 log.println("Actual result is: lRes = " + lRes 169 + "; lDone = " + lDone[0]); 170 171 bRes = bRes && lRes == previousCharacters[i][2]; 172 bRes = bRes && lDone[0] == previousCharacters[i][3]; 173 } 174 175 tRes.tested("previousCharacters()", bRes); 176 } 177 178 Vector vBounds = new Vector(); 179 180 /** 181 * Saves bounds of all returned words for the future tests. <p> 182 * Has <b>OK</b> status. 183 */ _nextWord()184 public void _nextWord() { 185 int i = 0; 186 187 while( i < UnicodeString.length() - 1 ) { 188 Boundary bounds = oObj.nextWord 189 (UnicodeString, i, locale, wordType); 190 if (bounds.endPos - bounds.startPos > 3) { 191 vBounds.add( bounds ); 192 log.println("Word " + vBounds.size() + "(" 193 + bounds.startPos + "," + bounds.endPos + "): '" + 194 UnicodeString.substring(bounds.startPos, 195 bounds.endPos) + "'"); 196 } 197 i = bounds.endPos - 1; 198 } 199 log.println("In text there are " + vBounds.size() 200 + " words, if count from left to right"); 201 tRes.tested("nextWord()", true); 202 } 203 204 /** 205 * Compares number of word bounds with number of word bounds saved 206 * by the method _nextWord().<p> 207 * Has <b>OK</b> status if number of word bounds are equal. 208 */ _previousWord()209 public void _previousWord() { 210 requiredMethod("nextWord()"); 211 212 int i = UnicodeString.length() - 1; 213 Vector vPrevBounds = new Vector(); 214 while( i > 0 ) { 215 Boundary bounds = 216 oObj.previousWord(UnicodeString, i, locale, wordType); 217 if (bounds.endPos - bounds.startPos > 3) { 218 vPrevBounds.add( bounds ); 219 log.println("Word " + vPrevBounds.size() + "(" 220 + bounds.startPos + "," + bounds.endPos + "): '" 221 + UnicodeString.substring(bounds.startPos, bounds.endPos) 222 + "'"); 223 } 224 i = bounds.startPos; 225 } 226 log.println("In text there are " + vPrevBounds.size() 227 + " words, if count from right to left"); 228 tRes.tested("previousWord()", vPrevBounds.size() == vBounds.size() ); 229 } 230 231 /** 232 * For every word in array obtained by <code>nextWord</code> method test 233 * computes bounds of the word, passing its internal character position.<p> 234 * 235 * Has <b>OK</b> status if bounds calculated by <code>getWordBoundary()</code> 236 * method are the same as bounds obtained by <code>nextWord</code> method. 237 */ _getWordBoundary()238 public void _getWordBoundary() { 239 requiredMethod("nextWord()"); 240 241 boolean bRes = true; 242 243 for(int i = 0; i < vBounds.size(); i++) { 244 // calculate middle of the word 245 Boundary iBounds = (Boundary)vBounds.get(i); 246 int iPos = (iBounds.endPos - iBounds.startPos) / 2 247 + iBounds.startPos; 248 Boundary bounds = oObj.getWordBoundary(UnicodeString, iPos, 249 locale, wordType, true); 250 log.println("Expected result is: startPos = " + iBounds.startPos + 251 "; endPos = " + iBounds.endPos); 252 log.println("Actual result is: startPos = " + bounds.startPos 253 + "; endPos = " + bounds.endPos + " Word is: '" 254 + UnicodeString.substring(bounds.startPos, bounds.endPos) + "'"); 255 256 bRes = bRes && iBounds.startPos == bounds.startPos; 257 bRes = bRes && iBounds.endPos == bounds.endPos; 258 } 259 260 tRes.tested("getWordBoundary()", bRes); 261 } 262 263 /** 264 * For every word in array obtained by <code>nextWord</code> method test 265 * get its type, passing its internal character position.<p> 266 * 267 * Has <b>OK</b> status if every word has type <code>WordType.ANY_WORD</code> 268 */ _getWordType()269 public void _getWordType() { 270 requiredMethod("nextWord()"); 271 272 boolean bRes = true; 273 274 for(int i = 0; i < vBounds.size(); i++) { 275 // calculate middle of the word 276 Boundary iBounds = (Boundary)vBounds.get(i); 277 int iPos = (iBounds.endPos - iBounds.startPos) / 2 278 + iBounds.startPos; 279 280 short type = oObj.getWordType(UnicodeString, iPos, locale); 281 282 bRes = bRes && type == WordType.ANY_WORD; 283 } 284 285 tRes.tested("getWordType()", bRes); 286 } 287 288 /** 289 * For every word in array obtained by <code>nextWord</code> method test 290 * tries to determine if the character at a position starts a word. 291 * First word starting position is passed, then internal character 292 * position is passed. <p> 293 * Has <b>OK</b> status if in the first case <code>true</code> 294 * returned and in the second - <code>false</code> for every word. 295 */ _isBeginWord()296 public void _isBeginWord() { 297 requiredMethod("nextWord()"); 298 299 boolean bRes = true; 300 301 for(int i = 0; i < vBounds.size(); i++) { 302 Boundary iBounds = (Boundary)vBounds.get(i); 303 boolean isBegin = oObj.isBeginWord(UnicodeString, iBounds.startPos, 304 locale, WordType.ANY_WORD); 305 bRes = bRes && isBegin; 306 boolean isNotBegin = !oObj.isBeginWord(UnicodeString, 307 iBounds.startPos + 1, locale, WordType.ANY_WORD); 308 bRes = bRes && isNotBegin; 309 310 log.println("At position + " + iBounds.startPos 311 + " isBeginWord? " + isBegin); 312 log.println("At position + " + (iBounds.startPos + 1) 313 + " isBeginWord? " + !isNotBegin); 314 } 315 316 tRes.tested("isBeginWord()", bRes); 317 } 318 319 /** 320 * For every word in array obtained by <code>nextWord</code> method test 321 * tries to determine if the character at a position ends a word. 322 * First word ending position is passed, then internal character 323 * position is passed. <p> 324 * 325 * Has <b>OK</b> status if in the first case <code>true</code> 326 * returned and in the second - <code>false</code> for every word. 327 */ _isEndWord()328 public void _isEndWord() { 329 requiredMethod("nextWord()"); 330 331 boolean bRes = true; 332 333 for(int i = 0; i < vBounds.size(); i++) { 334 Boundary iBounds = (Boundary)vBounds.get(i); 335 boolean isEnd = oObj.isEndWord(UnicodeString, iBounds.endPos, 336 locale, WordType.ANY_WORD); 337 bRes = bRes && isEnd; 338 boolean isNotEnd = !oObj.isEndWord(UnicodeString, 339 iBounds.endPos - 1, locale, WordType.ANY_WORD); 340 bRes = bRes && isNotEnd; 341 342 log.println("At position + " + iBounds.endPos 343 + " isEndWord? " + isEnd); 344 log.println("At position + " + (iBounds.endPos - 1) 345 + " isEndWord? " + !isNotEnd); 346 } 347 348 tRes.tested("isEndWord()", bRes); 349 } 350 351 Vector vSentenceStart = new Vector(); 352 /** 353 * Tries to find all sentences starting positions passing every character 354 * as position parameter and stores them. Then tries to pass invalid 355 * position parameters. 356 * 357 * Has <b>OK</b> status if -1 is returned for wrong position arguments. 358 */ _beginOfSentence()359 public void _beginOfSentence() { 360 int iPos = 0; 361 while( iPos < UnicodeString.length() ) { 362 Integer start = new Integer( oObj.beginOfSentence(UnicodeString, 363 iPos, locale) ); 364 if (start.intValue() >= 0 && !vSentenceStart.contains(start) ) { 365 vSentenceStart.add( start ); 366 log.println("Sentence " + vSentenceStart.size() 367 + " : start from position " + start); 368 } 369 iPos++; 370 } 371 372 //test for invalid nStartPosition 373 boolean bRes = oObj.beginOfSentence(UnicodeString, -10, locale) == -1; 374 bRes &= oObj.beginOfSentence(UnicodeString, 375 UnicodeString.length() + 1, locale) == -1; 376 377 if (!bRes) { 378 log.println("When invalid position, returned value isn't equal to -1"); 379 } 380 381 tRes.tested("beginOfSentence()", bRes); 382 } 383 384 /** 385 * For every sentence starting position found in 386 * <code>beginOfSentence()</code> test tries to compute end 387 * position of a sentence and checks that the end position is 388 * greater than starting. 389 * Then wrong position arguments are passed. 390 * 391 * Has <b>OK</b> status if the end position of every sentence 392 * greater than starting and -1 returned for invalid arguments. 393 */ _endOfSentence()394 public void _endOfSentence() { 395 boolean bRes = true; 396 for(int i = 0; i < vSentenceStart.size(); i++) { 397 int start = ((Integer)vSentenceStart.get(i)).intValue(); 398 int end = oObj.endOfSentence(UnicodeString, start, locale); 399 bRes &= end > start; 400 log.println("Sentence " + i + " range is [" + start + ", " 401 + end + "]"); 402 } 403 404 //test for invalid nStartPosition 405 boolean bInvRes = oObj.endOfSentence(UnicodeString, -10, locale) == -1; 406 bInvRes &= oObj.endOfSentence(UnicodeString, 407 UnicodeString.length() + 1, locale) == -1; 408 409 if (!bInvRes) { 410 log.println("When invalid position, returned value isn't equal to -1"); 411 } 412 413 tRes.tested("endOfSentence()", bRes && bInvRes); 414 } 415 416 /** 417 * Tries to break a string in position other than 0 iterating characters 418 * from the string beginning (Hyphenation is not used for a while). <p> 419 * 420 * Has <b>OK</b> status if non-zero break position was found and it is 421 * less or equal than position we trying to break. 422 */ _getLineBreak()423 public void _getLineBreak() { 424 boolean bRes = true; 425 LineBreakResults lineBreakResults; 426 LineBreakHyphenationOptions lineBreakHyphenationOptions = 427 new LineBreakHyphenationOptions(); 428 LineBreakUserOptions lineBreakUserOptions = new LineBreakUserOptions(); 429 430 lineBreakUserOptions.applyForbiddenRules = false; 431 lineBreakUserOptions.allowHyphenateEnglish = false; 432 433 int breakPos = 0; 434 int pos = 0; 435 436 while(breakPos == 0 && pos < UnicodeString.length() ) { 437 lineBreakResults = oObj.getLineBreak(UnicodeString, pos, 438 locale, 0, lineBreakHyphenationOptions, lineBreakUserOptions); 439 breakPos = lineBreakResults.breakIndex; 440 pos++; 441 } 442 443 // finally the position of break must be found in the middle and 444 // it must be before the break position specified 445 bRes = breakPos <= pos && breakPos > 0; 446 447 if (!bRes) { 448 log.println("The last position was: " + pos 449 + ", and the break position was: " + breakPos); 450 } 451 452 tRes.tested("getLineBreak()", bRes); 453 } 454 455 // Asian type script 456 private static String katakana = new String(new char[] {0x30A1, 0x30A2}) ; 457 // Weak type script 458 private static String arrows = new String(new char[] {0x2190, 0x2191}) ; 459 // Complex type script 460 private static String arabic = new String(new char[] {0x0641, 0x0642}) ; 461 462 /** 463 * Tries to find the beginning of the nearest script specified 464 * relatively to position passed. <p> 465 * Has <b>OK</b> status if the starting position of script is returned. 466 */ _beginOfScript()467 public void _beginOfScript() { 468 String multiScript = "ab" + katakana ; 469 470 int pos = oObj.beginOfScript(multiScript, 3, ScriptType.ASIAN) ; 471 472 log.println("Position = " + pos) ; 473 474 tRes.tested("beginOfScript()", pos == 2) ; 475 } 476 477 /** 478 * Tries to find the end of the nearest script specified 479 * relatively to position passed. <p> 480 * Has <b>OK</b> status if the end position of script is returned. 481 */ _endOfScript()482 public void _endOfScript() { 483 String multiScript = "ab" + katakana + "cd" ; 484 485 int pos = oObj.endOfScript(multiScript, 2, ScriptType.ASIAN) ; 486 487 log.println("Position = " + pos) ; 488 489 tRes.tested("endOfScript()", pos == 4) ; 490 } 491 492 /** 493 * Tries to find the next script starting position specified 494 * relatively to position passed. <p> 495 * Has <b>OK</b> status if the appropriate position is returned. 496 */ _nextScript()497 public void _nextScript() { 498 String multiScript = "ab" + katakana + "cd" ; 499 500 int pos = oObj.nextScript(multiScript, 0, ScriptType.LATIN) ; 501 502 log.println("Position = " + pos) ; 503 504 tRes.tested("nextScript()", pos == 4) ; 505 } 506 507 /** 508 * Tries to find the previous script starting position specified 509 * relatively to position passed. <p> 510 * Has <b>OK</b> status if the appropriate position is returned. 511 */ _previousScript()512 public void _previousScript() { 513 String multiScript = "ab" + katakana + "cd" ; 514 515 int pos = oObj.previousScript(multiScript, 5, ScriptType.ASIAN) ; 516 517 log.println("Position = " + pos) ; 518 519 tRes.tested("previousScript()", pos == 2) ; 520 } 521 522 /** 523 * Tries to determine script type (of all four types). <p> 524 * Has <b>OK</b> status if <code>LATIN</code> type returned 525 * for ACSII character, <code>ASIAN</code> for Katakana Unicode 526 * codepoints, <code>COMPLEX</code> for Arabic Unicode 527 * codepoints and <code>WEAK</code> for codepoints from Arrows 528 * Unicode block. 529 */ _getScriptType()530 public void _getScriptType() { 531 boolean res = true ; 532 533 res &= oObj.getScriptType("abcd", 0) == ScriptType.LATIN ; 534 res &= oObj.getScriptType(katakana, 0) == ScriptType.ASIAN; 535 res &= oObj.getScriptType(arabic, 0) == ScriptType.COMPLEX ; 536 res &= oObj.getScriptType(arrows, 0) == ScriptType.WEAK ; 537 538 tRes.tested("getScriptType()", res) ; 539 } 540 541 boolean bCharBlockRes = true; 542 getCharBlockType(int pos)543 protected short getCharBlockType(int pos) { 544 short i = 1; 545 short cType = 0; 546 while (i < 31) { 547 if (oObj.beginOfCharBlock(UnicodeString, pos, locale, i) != -1) { 548 cType = i; 549 i = 100; 550 } 551 i++; 552 } 553 554 return cType; 555 } 556 557 Vector vCharBlockBounds = new Vector(); 558 Vector vCharBlockTypes = new Vector(); 559 560 /** 561 * Creates array of all char blocks with their boundaries and 562 * types using <code>beginOfCharBlock()</code> and 563 * <code>endOfCharBlock()</code> methods. <p> 564 * 565 * Has <b>OK</b> status if the end of each boundary is the same 566 * as start of the next one and if the start of the first block 567 * has position 0 and the end of the last block is at the end 568 * of the whole string. 569 */ _beginOfCharBlock()570 public void _beginOfCharBlock() { 571 int iPos = 0; 572 573 while( iPos < UnicodeString.length() && iPos > -1) { 574 short charType = getCharBlockType(iPos); 575 int startPos = oObj.beginOfCharBlock(UnicodeString, iPos, 576 locale, charType); 577 int endPos = oObj.endOfCharBlock(UnicodeString, iPos, 578 locale, charType); 579 iPos = endPos; 580 vCharBlockBounds.add(new Boundary(startPos, endPos)); 581 log.println("" + vCharBlockBounds.size() + "). Bounds: [" 582 + startPos + "," + endPos + "]; Type = " + charType); 583 vCharBlockTypes.add(new Short(charType)); 584 } 585 586 for(int i = 0; i < vCharBlockBounds.size() - 1; i++) { 587 int endPos = ((Boundary)vCharBlockBounds.get(i)).endPos; 588 int startPos = ((Boundary)vCharBlockBounds.get(i + 1)).startPos; 589 bCharBlockRes &= endPos == startPos; 590 } 591 592 log.println("Testing for no intersections : " + bCharBlockRes); 593 int startPos = ((Boundary)vCharBlockBounds.get(0)).startPos; 594 bCharBlockRes &= startPos == 0; 595 int endPos = ((Boundary)vCharBlockBounds.get 596 (vCharBlockBounds.size() - 1)).endPos; 597 bCharBlockRes &= endPos == UnicodeString.length(); 598 log.println("Regions should starts with 0 and ends with " 599 + UnicodeString.length()); 600 601 tRes.tested("beginOfCharBlock()", bCharBlockRes); 602 } 603 604 /** 605 * Testing of this method is performed in <code>beginOfCharBlock()</code> 606 * method test. <p> 607 * 608 * Has the status same as <code>beginOfCharBlock()</code> method status. 609 */ _endOfCharBlock()610 public void _endOfCharBlock() { 611 requiredMethod("beginOfCharBlock()"); 612 tRes.tested("endOfCharBlock()", bCharBlockRes); 613 } 614 615 /** 616 * For every character block obtained in <code>beginOfCharBlock()</code> 617 * method test (except the first) tries to find its starting position 618 * by mean of <code>nextCharBlock()</code> method passing as position 619 * argument the position before the start of a block. <p> 620 * 621 * Has <b>OK</b> status if the start of every block was found and it's 622 * equal to this block boundary start. 623 */ _nextCharBlock()624 public void _nextCharBlock() { 625 requiredMethod("beginOfCharBlock()"); 626 627 boolean bRes = true; 628 for(int i = 0; i < vCharBlockBounds.size(); i++) { 629 Boundary bounds = (Boundary)vCharBlockBounds.get(i); 630 Short type = (Short)vCharBlockTypes.get(i); 631 if (bounds.startPos - 1 < 0) continue; 632 int iPos = oObj.nextCharBlock(UnicodeString, bounds.startPos - 1, 633 locale, type.shortValue()); 634 if (iPos != bounds.startPos) { 635 bRes = false; 636 log.println("nextCharBlock(UnicodeString, " 637 + (bounds.startPos - 1) + ", locale, " + type 638 + ") should return " + bounds.startPos); 639 log.println("... and actual value is " + iPos); 640 } 641 } 642 643 tRes.tested("nextCharBlock()", bRes); 644 } 645 646 /** 647 * For every character block obtained in <code>beginOfCharBlock()</code> 648 * method test (except the first) tries to find its starting position 649 * by mean of <code>previousCharBlock()</code> method passing as position 650 * argument the position after the end of a block. <p> 651 * 652 * Has <b>OK</b> status if the start of every block was found and it's 653 * equal to this block boundary start. 654 */ _previousCharBlock()655 public void _previousCharBlock() { 656 requiredMethod("beginOfCharBlock()"); 657 658 boolean bRes = true; 659 for(int i = 0; i < vCharBlockBounds.size(); i++) { 660 Boundary bounds = (Boundary)vCharBlockBounds.get(i); 661 Short type = (Short)vCharBlockTypes.get(i); 662 int iPos = oObj.previousCharBlock(UnicodeString, 663 bounds.endPos + 1, locale, type.shortValue()); 664 if (iPos != bounds.startPos) { 665 bRes = false; 666 log.println("previousCharBlock(UnicodeString, " 667 + (bounds.endPos + 1) + ", locale, " + type 668 + ") should return " + bounds.startPos); 669 log.println("... and actual value is " + iPos); 670 } 671 } 672 673 tRes.tested("previousCharBlock()", bRes); 674 } 675 676 } 677 678