blob: 5f6e3412b6f02f59900eb2136f2b822506b6c135 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 2001-2013, 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;
/**
* Regression test for the basic "inverse" Bidi mode.
*
* ported from C by Lina Kemmel, Matitiahu Allouche
*/
public class TestInverse extends BidiTest {
private int countRoundtrips = 0;
private int countNonRoundtrips = 0;
static final String[] testCases = {
"\u006c\u0061\u0028\u0074\u0069\u006e\u0020\u05d0\u05d1\u0029\u05d2\u05d3",
"\u006c\u0061\u0074\u0020\u05d0\u05d1\u05d2\u0020\u0031\u0032\u0033",
"\u006c\u0061\u0074\u0020\u05d0\u0028\u05d1\u05d2\u0020\u0031\u0029\u0032\u0033",
"\u0031\u0032\u0033\u0020\u05d0\u05d1\u05d2\u0020\u0034\u0035\u0036",
"\u0061\u0062\u0020\u0061\u0062\u0020\u0661\u0662"
};
public void testInverse() {
Bidi bidi;
int i;
logln("\nEntering TestInverse\n");
bidi = new Bidi();
log("inverse Bidi: testInverse(L) with " + testCases.length +
" test cases ---\n");
for(i = 0; i < testCases.length; ++i) {
logln("Testing case " + i);
_testInverseBidi(bidi, testCases[i], Bidi.DIRECTION_LEFT_TO_RIGHT);
}
log("inverse Bidi: testInverse(R) with " + testCases.length +
" test cases ---\n");
for (i = 0; i < testCases.length; ++i) {
logln("Testing case " + i);
_testInverseBidi(bidi, testCases[i], Bidi.DIRECTION_RIGHT_TO_LEFT);
}
_testManyInverseBidi(bidi, Bidi.DIRECTION_LEFT_TO_RIGHT);
_testManyInverseBidi(bidi, Bidi.DIRECTION_RIGHT_TO_LEFT);
logln("inverse Bidi: rountrips: " + countRoundtrips +
" non-roundtrips: " + countNonRoundtrips);
_testWriteReverse();
_testManyAddedPoints();
_testMisc();
logln("\nExiting TestInverse\n");
}
private static final char[][] repeatSegments = {
{ 0x61, 0x62 }, /* L */
{ 0x5d0, 0x5d1 }, /* R */
{ 0x627, 0x628 }, /* AL */
{ 0x31, 0x32 }, /* EN */
{ 0x661, 0x662 }, /* AN */
{ 0x20, 0x20 } /* WS (N) */
};
private static final int COUNT_REPEAT_SEGMENTS = 6;
private void _testManyInverseBidi(Bidi bidi, int direction) {
char[] text = { 0, 0, 0x20, 0, 0, 0x20, 0, 0 };
int i, j, k;
log("inverse Bidi: testManyInverseBiDi(" +
(direction == Bidi.DIRECTION_LEFT_TO_RIGHT ? 'L' : 'R') +
") - test permutations of text snippets ---\n");
for (i = 0; i < COUNT_REPEAT_SEGMENTS; ++i) {
text[0] = repeatSegments[i][0];
text[1] = repeatSegments[i][1];
for (j = 0; j < COUNT_REPEAT_SEGMENTS; ++j) {
text[3] = repeatSegments[j][0];
text[4] = repeatSegments[j][1];
for (k = 0; k < COUNT_REPEAT_SEGMENTS; ++k) {
text[6] = repeatSegments[k][0];
text[7] = repeatSegments[k][1];
log("inverse Bidi: testManyInverseBiDi()[" +
i + " " + j + " " + k + "]\n");
_testInverseBidi(bidi, new String(text), direction);
}
}
}
}
private void _testInverseBidi(Bidi bidi, String src, int direction) {
String visualLTR, logicalDest, visualDest;
try {
if (direction == Bidi.DIRECTION_LEFT_TO_RIGHT) {
log("inverse Bidi: testInverse(L)\n");
/* convert visual to logical */
bidi.setInverse(true);
if (!bidi.isInverse()) {
err("Error while doing setInverse(true)\n");
}
bidi.setPara(src, Bidi.LTR, null);
if (!Arrays.equals(src.toCharArray(), bidi.getText())) {
err("Wrong value returned by getText\n");
}
if (!src.equals(bidi.getTextAsString())) {
err("Wrong value returned by getTextAsString\n");
}
logicalDest = bidi.writeReordered(Bidi.DO_MIRRORING |
Bidi.INSERT_LRM_FOR_NUMERIC);
log(" v ");
printUnicode(src.toCharArray(), bidi.getLevels());
log("\n");
/* convert back to visual LTR */
bidi.setInverse(false);
if (bidi.isInverse()) {
err("Error while doing setInverse(false)\n");
}
bidi.setPara(logicalDest, Bidi.LTR, null);
visualDest = bidi.writeReordered(Bidi.DO_MIRRORING |
Bidi.REMOVE_BIDI_CONTROLS);
} else {
logln("inverse Bidi: testInverse(R)\n");
/* reverse visual from RTL to LTR */
visualLTR = Bidi.writeReverse(src, 0);
log(" vr");
printUnicode(src.toCharArray(), null);
log("\n");
/* convert visual RTL to logical */
bidi.setInverse(true);
bidi.setPara(visualLTR, Bidi.LTR, null);
logicalDest = bidi.writeReordered(Bidi.DO_MIRRORING |
Bidi.INSERT_LRM_FOR_NUMERIC);
log(" vl");
printUnicode(visualLTR.toCharArray(), bidi.getLevels());
log("\n");
/* convert back to visual RTL */
bidi.setInverse(false);
bidi.setPara(logicalDest, Bidi.LTR, null);
visualDest = bidi.writeReordered(Bidi.DO_MIRRORING |
Bidi.REMOVE_BIDI_CONTROLS | Bidi.OUTPUT_REVERSE);
}
log(" l ");
printUnicode(logicalDest.toCharArray(), bidi.getLevels());
log("\n");
log(" v ");
printUnicode(visualDest.toCharArray(), null);
log("\n");
} catch (Exception e) {
errln("\ninverse Bidi: *** failed");
errln(" error message: " + e.getMessage());
e.printStackTrace();
visualDest = null;
}
/* check and print results */
if (src.equals(visualDest)) {
++countRoundtrips;
log(" + roundtripped\n");
} else {
++countNonRoundtrips;
log(" * did not roundtrip\n");
}
}
private void _testWriteReverse() {
/* U+064e and U+0650 are combining marks (Mn) */
final String
forward = "\u200f\u0627\u064e\u0650\u0020\u0028\u0031\u0029",
reverseKeepCombining =
"\u0029\u0031\u0028\u0020\u0627\u064e\u0650\u200f",
reverseRemoveControlsKeepCombiningDoMirror =
"\u0028\u0031\u0029\u0020\u0627\u064e\u0650";
String reverse;
/* test Bidi.writeReverse() with "interesting" options */
try {
reverse = Bidi.writeReverse(forward, Bidi.KEEP_BASE_COMBINING);
} catch (Exception e) {
errln("Failure in Bidi.writeReverse(KEEP_BASE_COMBINING)");
reverse = null;
}
assertEquals("\nFailure in " + getClass().toString() +
" in Bidi.writeReverse", reverseKeepCombining,
reverse, forward, null, "KEEP_BASE_COMBINING", null);
try {
reverse = Bidi.writeReverse(forward, Bidi.REMOVE_BIDI_CONTROLS |
Bidi.DO_MIRRORING | Bidi.KEEP_BASE_COMBINING);
} catch (Exception e) {
errln("Failure in Bidi.writeReverse(KEEP_BASE_COMBINING)");
}
assertEquals("\nFailure in " + getClass().toString() +
" in Bidi.writeReverse",
reverseRemoveControlsKeepCombiningDoMirror,
reverse, forward, null,
"REMOVE_BIDI_CONTROLS|DO_MIRRORING|KEEP_BASE_COMBINING",
null);
}
private void printUnicode(char[] chars, byte[] levels) {
int i;
log("{ ");
for (i = 0; i < chars.length; ++i) {
log("0x" + Utility.hex(chars[i]));
if (levels != null) {
log("." + levels[i]);
}
log(" ");
}
log(" }");
}
private void _testManyAddedPoints() {
Bidi bidi = new Bidi();
char[] text = new char[90];
for (int i = 0; i < text.length; i+=3) {
text[i] = 'a';
text[i+1] = '\u05d0';
text[i+2] = '3';
}
bidi.setReorderingMode(Bidi.REORDER_INVERSE_LIKE_DIRECT);
bidi.setReorderingOptions(Bidi.OPTION_INSERT_MARKS);
bidi.setPara(text, Bidi.LTR, null);
String out = bidi.writeReordered(0);
char[] expected = new char[120];
for (int i = 0; i < expected.length; i+=4) {
expected[i] = 'a';
expected[i+1] = '\u05d0';
expected[i+2] = '\u200e';
expected[i+3] = '3';
}
assertEquals("\nInvalid output with many added points",
new String(expected), out);
}
private void _testMisc() {
Bidi bidi = new Bidi();
bidi.setInverse(true);
bidi.setPara(" ", Bidi.RTL, null);
String out = bidi.writeReordered(Bidi.OUTPUT_REVERSE | Bidi.INSERT_LRM_FOR_NUMERIC);
assertEquals("\nInvalid output with RLM at both sides",
"\u200f \u200f", out);
}
public static void main(String[] args) {
try {
new TestInverse().run(args);
}
catch (Exception e) {
System.out.println(e);
}
}
}