blob: 8842ec18f8051a28b508f36e6af72e0b5266f967 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 2008-2010, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.dev.test.bidi;
import java.util.Arrays;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.text.Bidi;
import com.ibm.icu.text.BidiRun;
/**
* Regression test for Bidi multiple paragraphs
*
* @author Lina Kemmel, Matitiahu Allouche
*/
public class TestMultipleParagraphs extends BidiTest {
private static final String text =
"__ABC\u001c" /* Para #0 offset 0 */
+ "__\u05d0DE\u001c" /* 1 6 */
+ "__123\u001c" /* 2 12 */
+ "\r\n" /* 3 18 */
+ "FG\r" /* 4 20 */
+ "\r" /* 5 23 */
+ "HI\r\n" /* 6 24 */
+ "\r\n" /* 7 28 */
+ "\n" /* 8 30 */
+ "\n" /* 9 31 */
+ "JK\u001c"; /* 10 32 */
private static final int paraCount = 11;
private static final int[] paraBounds = {
0, 6, 12, 18, 20, 23, 24, 28, 30, 31, 32, 35
};
private static final byte[] paraLevels = {
Bidi.LTR, Bidi.RTL, Bidi.LEVEL_DEFAULT_LTR, Bidi.LEVEL_DEFAULT_RTL, 22, 23
};
private static final byte[][] multiLevels = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0},
{22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22},
{23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23}
};
private static final String text2 = "\u05d0 1-2\u001c\u0630 1-2\u001c1-2";
private static final byte[] levels2 = {
1, 1, 2, 2, 2, 0, 1, 1, 2, 1, 2, 0, 2, 2, 2
};
private static final char[] multiparaTestString = {
0x5de, 0x5e0, 0x5e1, 0x5d4, 0x20, 0x5e1, 0x5e4, 0x5da,
0x20, 0xa, 0xa, 0x41, 0x72, 0x74, 0x69, 0x73,
0x74, 0x3a, 0x20, 0x5de, 0x5e0, 0x5e1, 0x5d4, 0x20,
0x5e1, 0x5e4, 0x5da, 0x20, 0xa, 0xa, 0x41, 0x6c,
0x62, 0x75, 0x6d, 0x3a, 0x20, 0x5de, 0x5e0, 0x5e1,
0x5d4, 0x20, 0x5e1, 0x5e4, 0x5da, 0x20, 0xa, 0xa,
0x54, 0x69, 0x6d, 0x65, 0x3a, 0x20, 0x32, 0x3a,
0x32, 0x37, 0xa, 0xa
};
private static final byte[] multiparaTestLevels = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1,
1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
};
public void testMultipleParagraphs()
{
byte gotLevel;
byte[] gotLevels;
boolean orderParagraphsLTR;
String src;
Bidi bidi = new Bidi();
Bidi bidiLine;
int count, paraStart, paraLimit, paraIndex, length;
int i, j, k;
logln("\nEntering TestMultipleParagraphs\n");
try {
bidi.setPara(text, Bidi.LTR, null);
} catch (IllegalArgumentException e) {
errln("1st Bidi.setPara failed, paraLevel = " + Bidi.LTR);
}
/* check paragraph count and boundaries */
if (paraCount != (count = bidi.countParagraphs())) {
errln("1st Bidi.countParagraphs returned " + count + ", should be " +
paraCount);
}
BidiRun run;
for (i = 0; i < paraCount; i++) {
run = bidi.getParagraphByIndex(i);
paraStart = run.getStart();
paraLimit = run.getLimit();
if ((paraStart != paraBounds[i]) ||
(paraLimit != paraBounds[i + 1])) {
errln("Found boundaries of paragraph " + i + ": " +
paraStart + "-" + paraLimit + "; expected: " +
paraBounds[i] + "-" + paraBounds[i + 1]);
}
}
/* check with last paragraph not terminated by B */
char[] chars = text.toCharArray();
chars[chars.length - 1] = 'L';
src = new String(chars);
try {
bidi.setPara(src, Bidi.LTR, null);
} catch (IllegalArgumentException e) {
errln("2nd Bidi.setPara failed, paraLevel = " + Bidi.LTR);
}
if (paraCount != (count = bidi.countParagraphs())) {
errln("2nd Bidi.countParagraphs returned " + count +
", should be " + paraCount);
}
i = paraCount - 1;
run = bidi.getParagraphByIndex(i);
paraStart = run.getStart();
paraLimit = run.getLimit();
if ((paraStart != paraBounds[i]) ||
(paraLimit != paraBounds[i + 1])) {
errln("2nd Found boundaries of paragraph " + i + ": " +
paraStart + "-" + paraLimit + "; expected: " +
paraBounds[i] + "-" + paraBounds[i + 1]);
}
/* check paraLevel for all paragraphs under various paraLevel specs */
for (k = 0; k < 6; k++) {
try {
bidi.setPara(src, paraLevels[k], null);
} catch (IllegalArgumentException e) {
errln("3nd Bidi.setPara failed, paraLevel = " + paraLevels[k]);
}
for (i = 0; i < paraCount; i++) {
paraIndex = bidi.getParagraphIndex(paraBounds[i]);
run = bidi.getParagraph(paraBounds[i]);
if (paraIndex != i) {
errln("#1 For paraLevel = " + paraLevels[k] +
" paragraph = " + i + ", found paragraph" +
" index = " + paraIndex + " expected = " + i);
}
gotLevel = run.getEmbeddingLevel();
if (gotLevel != multiLevels[k][i]) {
errln("#2 For paraLevel = " + paraLevels[k] +
" paragraph = " + i + ", found level = " + gotLevel +
", expected = " + multiLevels[k][i]);
}
}
gotLevel = bidi.getParaLevel();
if (gotLevel != multiLevels[k][0]) {
errln("#3 For paraLevel = " + paraLevels[k] +
" getParaLevel = " + gotLevel + ", expected " +
multiLevels[k][0]);
}
}
/* check that the result of Bidi.getParaLevel changes if the first
* paragraph has a different level
*/
chars[0] = '\u05d2'; /* Hebrew letter Gimel */
src = new String(chars);
try {
bidi.setPara(src, Bidi.LEVEL_DEFAULT_LTR, null);
} catch (IllegalArgumentException e) {
errln("Bidi.setPara failed, paraLevel = " + Bidi.LEVEL_DEFAULT_LTR);
}
gotLevel = bidi.getParaLevel();
if (gotLevel != Bidi.RTL) {
errln("#4 For paraLevel = Bidi.LEVEL_DEFAULT_LTR getParaLevel = " +
gotLevel + ", expected = " + Bidi.RTL);
}
/* check that line cannot overlap paragraph boundaries */
bidiLine = new Bidi();
i = paraBounds[1];
k = paraBounds[2] + 1;
try {
bidiLine = bidi.setLine(i, k);
errln("For line limits " + i + "-" + k
+ " got success, while expected failure");
} catch (Exception e) {}
i = paraBounds[1];
k = paraBounds[2];
try {
bidiLine = bidi.setLine(i, k);
} catch (Exception e) {
errln("For line limits " + i + "-" + k + " got failure");
}
/* check level of block separator at end of paragraph when orderParagraphsLTR==FALSE */
try {
bidi.setPara(src, Bidi.RTL, null);
} catch (IllegalArgumentException e) {
errln("Bidi.setPara failed, paraLevel = " + Bidi.RTL);
}
/* get levels through para Bidi block */
try {
gotLevels = bidi.getLevels();
} catch (Exception e) {
errln("Error on Bidi.getLevels");
gotLevels = new byte[bidi.getLength()];
Arrays.fill(gotLevels, (byte)-1);
}
for (i = 26; i < 32; i++) {
if (gotLevels[i] != Bidi.RTL) {
errln("For char " + i + "(0x" + Utility.hex(chars[i]) +
"), level = " + gotLevels[i] + ", expected = " + Bidi.RTL);
}
}
/* get levels through para Line block */
i = paraBounds[1];
k = paraBounds[2];
try {
bidiLine = bidi.setLine(i, k);
} catch (Exception e) {
errln("For line limits " + i + "-" + k + " got failure");
return;
}
paraIndex = bidiLine.getParagraphIndex(i);
run = bidiLine.getParagraph(i);
try {
gotLevels = bidiLine.getLevels();
} catch (Exception e) {
errln("Error on bidiLine.getLevels");
gotLevels = new byte[bidiLine.getLength()];
Arrays.fill(gotLevels, (byte)-1);
}
length = bidiLine.getLength();
gotLevel = run.getEmbeddingLevel();
if ((gotLevel != Bidi.RTL) || (gotLevels[length - 1] != Bidi.RTL)) {
errln("For paragraph " + paraIndex + " with limits " +
run.getStart() + "-" + run.getLimit() +
", paraLevel = " + gotLevel +
"expected = " + Bidi.RTL +
", level of separator = " + gotLevels[length - 1] +
" expected = " + Bidi.RTL);
}
orderParagraphsLTR = bidi.isOrderParagraphsLTR();
assertFalse("orderParagraphsLTR is true", orderParagraphsLTR);
bidi.orderParagraphsLTR(true);
orderParagraphsLTR = bidi.isOrderParagraphsLTR();
assertTrue("orderParagraphsLTR is false", orderParagraphsLTR);
/* check level of block separator at end of paragraph when orderParagraphsLTR==TRUE */
try {
bidi.setPara(src, Bidi.RTL, null);
} catch (IllegalArgumentException e) {
errln("Bidi.setPara failed, paraLevel = " + Bidi.RTL);
}
/* get levels through para Bidi block */
try {
gotLevels = bidi.getLevels();
} catch (Exception e) {
errln("Error on Bidi.getLevels");
gotLevels = new byte[bidi.getLength()];
Arrays.fill(gotLevels, (byte)-1);
}
for (i = 26; i < 32; i++) {
if (gotLevels[i] != 0) {
errln("For char " + i + "(0x" + Utility.hex(chars[i]) +
"), level = "+ gotLevels[i] + ", expected = 0");
}
}
/* get levels through para Line block */
i = paraBounds[1];
k = paraBounds[2];
paraStart = run.getStart();
paraLimit = run.getLimit();
try {
bidiLine = bidi.setLine(paraStart, paraLimit);
} catch (Exception e) {
errln("For line limits " + paraStart + "-" + paraLimit +
" got failure");
}
paraIndex = bidiLine.getParagraphIndex(i);
run = bidiLine.getParagraph(i);
try {
gotLevels = bidiLine.getLevels();
} catch (Exception e) {
errln("Error on bidiLine.getLevels");
gotLevels = new byte[bidiLine.getLength()];
Arrays.fill(gotLevels, (byte)-1);
}
length = bidiLine.getLength();
gotLevel = run.getEmbeddingLevel();
if ((gotLevel != Bidi.RTL) || (gotLevels[length - 1] != 0)) {
err("\nFor paragraph " + paraIndex + " with limits " +
run.getStart() + "-" + run.getLimit() +
", paraLevel = " + gotLevel + "expected = " + Bidi.RTL +
", level of separator = " + gotLevels[length - 1] +
" expected = 0\nlevels = ");
for (count = 0; count < length; count++) {
errcont(gotLevels[count] + " ");
}
errcont("\n");
}
/* test that the concatenation of separate invocations of the bidi code
* on each individual paragraph in order matches the levels array that
* results from invoking bidi once over the entire multiparagraph tests
* (with orderParagraphsLTR false, of course)
*/
src = text; /* restore original content */
bidi.orderParagraphsLTR(false);
try {
bidi.setPara(src, Bidi.LEVEL_DEFAULT_RTL, null);
} catch (IllegalArgumentException e) {
errln("Bidi.setPara failed, paraLevel = " + Bidi.LEVEL_DEFAULT_RTL);
}
try {
gotLevels = bidi.getLevels();
} catch (Exception e) {
errln("Error on bidiLine.getLevels");
gotLevels = new byte[bidi.getLength()];
Arrays.fill(gotLevels, (byte)-1);
}
for (i = 0; i < paraCount; i++) {
/* use pLine for individual paragraphs */
paraStart = paraBounds[i];
length = paraBounds[i + 1] - paraStart;
try {
bidiLine.setPara(src.substring(paraStart, paraStart + length),
Bidi.LEVEL_DEFAULT_RTL, null);
} catch (IllegalArgumentException e) {
errln("Bidi.setPara failed, paraLevel = " + Bidi.LEVEL_DEFAULT_RTL);
}
for (j = 0; j < length; j++) {
if ((k = bidiLine.getLevelAt(j)) !=
(gotLevel = gotLevels[paraStart + j])) {
errln("Checking paragraph concatenation: for paragraph[" +
i + "], char[" + j + "] = 0x" +
Utility.hex(src.charAt(paraStart + j)) +
", level = " + k + ", expected = " + gotLevel);
}
}
}
/* ensure that leading numerics in a paragraph are not treated as arabic
numerals because of arabic text in a preceding paragraph
*/
src = text2;
bidi.orderParagraphsLTR(true);
try {
bidi.setPara(src, Bidi.RTL, null);
} catch (IllegalArgumentException e) {
errln("Bidi.setPara failed, paraLevel = " + Bidi.RTL);
}
try {
gotLevels = bidi.getLevels();
} catch (Exception e) {
errln("Error on Bidi.getLevels");
gotLevels = new byte[bidi.getLength()];
Arrays.fill(gotLevels, (byte)-1);
}
for (i = 0, length = src.length(); i < length; i++) {
if (gotLevels[i] != levels2[i]) {
errln("Checking leading numerics: for char " + i + "(0x" +
Utility.hex(src.charAt(i)) + "), level = " +
gotLevels[i] + ", expected = " + levels2[i]);
}
}
/* check handling of whitespace before end of paragraph separator when
* orderParagraphsLTR==TRUE, when last paragraph has, and lacks, a terminating B
*/
chars = src.toCharArray();
Arrays.fill(chars, '\u0020');
bidi.orderParagraphsLTR(true);
for (i = 0x001c; i <= 0x0020; i += (0x0020-0x001c)) {
chars[4] = (char)i; /* with and without terminating B */
for (j = 0x0041; j <= 0x05d0; j += (0x05d0-0x0041)) {
chars[0] = (char)j; /* leading 'A' or Alef */
src = new String(chars);
for (gotLevel = 4; gotLevel <= 5; gotLevel++) {
/* test even and odd paraLevel */
try {
bidi.setPara(src, gotLevel, null);
} catch (IllegalArgumentException e) {
errln("Bidi.setPara failed, paraLevel = " + gotLevel);
}
try {
gotLevels = bidi.getLevels();
} catch (Exception e) {
errln("Error on Bidi.getLevels");
gotLevels = new byte[bidi.getLength()];
Arrays.fill(gotLevels, (byte)-1);
}
for (k = 1; k <= 3; k++) {
if (gotLevels[k] != gotLevel) {
errln("Checking trailing spaces for leading char 0x" +
Utility.hex(chars[0]) + ", last_char = " +
Utility.hex(chars[4]) + ", index = " + k +
"level = " + gotLevels[k] +
", expected = " + gotLevel);
}
}
}
}
}
/* check default orientation when inverse bidi and paragraph starts
* with LTR strong char and ends with RTL strong char, with and without
* a terminating B
*/
bidi.setReorderingMode(Bidi.REORDER_INVERSE_LIKE_DIRECT);
bidi.setPara("abc \u05d2\u05d1\n", Bidi.LEVEL_DEFAULT_LTR, null);
String out = bidi.writeReordered(0);
assertEquals("\nInvalid output", "\u05d1\u05d2 abc\n", out);
bidi.setPara("abc \u05d2\u05d1", Bidi.LEVEL_DEFAULT_LTR, null);
out = bidi.writeReordered(0);
assertEquals("\nInvalid output #1", "\u05d1\u05d2 abc", out);
/* check multiple paragraphs together with explicit levels
*/
bidi.setReorderingMode(Bidi.REORDER_DEFAULT);
gotLevels = new byte[] {0,0,0,0,0,0,0,0,0,0};
bidi.setPara("ab\u05d1\u05d2\n\u05d3\u05d4123", Bidi.LTR, gotLevels);
out = bidi.writeReordered(0);
assertEquals("\nInvalid output #2", "ab\u05d2\u05d1\n123\u05d4\u05d3", out);
assertEquals("\nInvalid number of paras", 2, bidi.countParagraphs());
logln("\nExiting TestMultipleParagraphs\n");
/* check levels in multiple paragraphs with default para level
*/
bidi = new Bidi();
bidi.setPara(multiparaTestString, Bidi.LEVEL_DEFAULT_LTR, null);
try {
gotLevels = bidi.getLevels();
} catch (Exception e) {
errln("Error on Bidi.getLevels for multiparaTestString");
return;
}
for (i = 0; i < multiparaTestString.length; i++) {
if (gotLevels[i] != multiparaTestLevels[i]) {
errln("Error on level for multiparaTestString at index " + i +
", expected=" + multiparaTestLevels[i] +
", actual=" + gotLevels[i]);
}
}
}
public static void main(String[] args) {
try {
new TestMultipleParagraphs().run(args);
}
catch (Exception e) {
System.out.println(e);
}
}
}