1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package org.apache.harmony.text.tests.java.text;
19
20import java.text.AttributedString;
21import java.text.Bidi;
22import java.util.Arrays;
23
24import junit.framework.TestCase;
25
26public class BidiTest extends TestCase {
27
28	Bidi bd;
29
30	public static void assertRunArrayEquals(int[][] expected, Bidi bidi) {
31		assertEquals("different length", expected.length, bidi.getRunCount());
32
33		FORRUN: for (int i = 0; i < bidi.getRunCount(); i++) {
34			int[] butWas = new int[] { bidi.getRunStart(i),
35					bidi.getRunLimit(i), bidi.getRunLevel(i) };
36
37			for (int j = 0; j < expected.length; j++) {
38				if (expected[j][0] == butWas[0] && expected[j][1] == butWas[1]
39						&& expected[j][2] == butWas[2]) {
40					continue FORRUN;
41				}
42			}
43			fail("expected [" + i + "] " + " start: " + butWas[0] + " limit: "
44					+ butWas[1] + " level: " + butWas[2]);
45		}
46	}
47
48	public void testNullPointerConstructor() {
49		try {
50			bd = new Bidi(null, Bidi.DIRECTION_RIGHT_TO_LEFT);
51			fail("should throw IAE");
52		} catch (IllegalArgumentException e) {
53			// expected
54		}
55
56		try {
57			bd = new Bidi(null, 0, new byte[] { 0 }, 0, 0,
58					Bidi.DIRECTION_RIGHT_TO_LEFT);
59			fail("should throw IAE");
60		} catch (IllegalArgumentException e) {
61			// expected
62		}
63
64		try {
65            bd = new Bidi(null);
66            fail("should throw IAE");
67        } catch (IllegalArgumentException e) {
68        }
69
70		bd = new Bidi("a".toCharArray(), 0, null, 0, 1,
71				Bidi.DIRECTION_RIGHT_TO_LEFT);
72	}
73
74	public void testBadLength() {
75		try {
76			bd = new Bidi("1".toCharArray(), 0, new byte[] { 0 }, 0, 20,
77					Bidi.DIRECTION_RIGHT_TO_LEFT);
78			fail("should throw IAE");
79		} catch (IllegalArgumentException e) {
80			// expected
81		}
82
83		try {
84			bd = new Bidi("1234567".toCharArray(), 0, new byte[] { 0 }, 0, 4,
85					Bidi.DIRECTION_RIGHT_TO_LEFT);
86			fail("should throw IAE");
87		} catch (IllegalArgumentException e) {
88			// expected
89		}
90
91		try {
92			bd = new Bidi("1234567".toCharArray(), 4, new byte[] { 0, 1, 2, 3,
93					4 }, 0, 5, Bidi.DIRECTION_RIGHT_TO_LEFT);
94			fail("should throw IAE");
95		} catch (IllegalArgumentException e) {
96			// expected
97		}
98
99		try {
100			bd = new Bidi("1234567".toCharArray(), 0, new byte[] { 0, 1, 2, 3,
101					4 }, 4, 5, Bidi.DIRECTION_RIGHT_TO_LEFT);
102			fail("should throw IAE");
103		} catch (IllegalArgumentException e) {
104			// expected
105		}
106
107        //regression for HARMONY-1031
108		try {
109			bd = new Bidi(new char[] { 't','t','t'}, -1, new byte[] { 2, 2 }, 1, 1, 1);
110			fail("should be IAE");
111		} catch (IllegalArgumentException e) {
112			// expected
113		}
114
115		try {
116			bd = new Bidi(new char[] { 't','t','t'}, 1, new byte[] { 2, 2 }, -1, 1, 1);
117			fail("should be IAE");
118		} catch (IllegalArgumentException e) {
119			// expected
120		}
121
122		try {
123			bd = new Bidi(new char[] { 't','t','t'}, 1, new byte[] { 2, 2 }, 1, -1, 1);
124			fail("should be IAE");
125		} catch (IllegalArgumentException e) {
126			// expected
127		}
128
129		try {
130			bd = new Bidi(new char[] {}, 5, new byte[] { 2, 2, 2, 2, 2, 2 }, 8, Integer.MAX_VALUE, 5);
131			fail("should be IAE");
132		} catch (IllegalArgumentException e) {
133			// expected
134		}
135
136        try {
137            bd = new Bidi(null, 5, null, 8, Integer.MAX_VALUE, 5);
138            fail("should be IAE");
139        } catch (IllegalArgumentException e) {
140            // expected
141        }
142
143		bd = new Bidi(new char[] {'o'}, 0, new byte[] { 2, 2}, 2, 0, 2 );
144	}
145
146	public void testEmptyParagraph() {
147		bd = new Bidi("", Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
148		assertTrue(bd.baseIsLeftToRight());
149		assertEquals(0, bd.getBaseLevel());
150		assertEquals(0, bd.getLength());
151		assertEquals(0, bd.getLevelAt(0));
152		assertEquals(0, bd.getLevelAt(1000));
153		assertEquals(1, bd.getRunCount());
154		assertRunArrayEquals(new int[][] { { 0, 0, 0 } }, bd);
155		assertTrue(bd.isLeftToRight());
156		assertFalse(bd.isMixed());
157		assertFalse(bd.isRightToLeft());
158
159		bd = new Bidi("", Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
160		assertFalse(bd.baseIsLeftToRight());
161		assertEquals(1, bd.getBaseLevel());
162		assertEquals(0, bd.getLength());
163		assertEquals(1, bd.getLevelAt(0));
164		assertEquals(1, bd.getLevelAt(1000));
165		assertEquals(1, bd.getRunCount());
166		assertRunArrayEquals(new int[][] { { 0, 0, 1 }, }, bd);
167		assertFalse(bd.isLeftToRight());
168		assertFalse(bd.isMixed());
169		assertTrue(bd.isRightToLeft());
170
171		bd = new Bidi("", Bidi.DIRECTION_LEFT_TO_RIGHT);
172		assertTrue(bd.baseIsLeftToRight());
173		assertEquals(0, bd.getBaseLevel());
174		assertEquals(0, bd.getLength());
175		assertEquals(0, bd.getLevelAt(0));
176		assertEquals(0, bd.getLevelAt(1000));
177		assertEquals(1, bd.getRunCount());
178		assertRunArrayEquals(new int[][] { { 0, 0, 0 }, }, bd);
179		assertTrue(bd.isLeftToRight());
180		assertFalse(bd.isMixed());
181		assertFalse(bd.isRightToLeft());
182
183		bd = new Bidi("", Bidi.DIRECTION_RIGHT_TO_LEFT);
184		assertFalse(bd.baseIsLeftToRight());
185		assertEquals(1, bd.getBaseLevel());
186		assertEquals(0, bd.getLength());
187		assertEquals(1, bd.getLevelAt(0));
188		assertEquals(1, bd.getLevelAt(1000));
189		assertEquals(1, bd.getRunCount());
190		assertRunArrayEquals(new int[][] { { 0, 0, 1 }, }, bd);
191		assertFalse(bd.isLeftToRight());
192		assertFalse(bd.isMixed());
193		assertTrue(bd.isRightToLeft());
194	}
195
196	public void testSpaceParagraph() {
197		bd = new Bidi(" ", Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
198		assertTrue(bd.baseIsLeftToRight());
199		assertEquals(0, bd.getBaseLevel());
200		assertEquals(1, bd.getLength());
201		assertEquals(0, bd.getLevelAt(0));
202		assertEquals(0, bd.getLevelAt(1000));
203		assertEquals(1, bd.getRunCount());
204		assertRunArrayEquals(new int[][] { { 0, 1, 0 }, }, bd);
205		assertTrue(bd.isLeftToRight());
206		assertFalse(bd.isMixed());
207		assertFalse(bd.isRightToLeft());
208
209		bd = new Bidi(" ", Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
210		assertFalse(bd.baseIsLeftToRight());
211		assertEquals(1, bd.getBaseLevel());
212		assertEquals(1, bd.getLength());
213		assertEquals(1, bd.getLevelAt(0));
214		assertEquals(1, bd.getLevelAt(1000));
215		assertEquals(1, bd.getRunCount());
216		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, }, bd);
217		assertFalse(bd.isLeftToRight());
218		assertFalse(bd.isMixed());
219		assertTrue(bd.isRightToLeft());
220
221		bd = new Bidi(" ", Bidi.DIRECTION_LEFT_TO_RIGHT);
222		assertTrue(bd.baseIsLeftToRight());
223		assertEquals(0, bd.getBaseLevel());
224		assertEquals(1, bd.getLength());
225		assertEquals(0, bd.getLevelAt(0));
226		assertEquals(0, bd.getLevelAt(1000));
227		assertEquals(1, bd.getRunCount());
228		assertRunArrayEquals(new int[][] { { 0, 1, 0 }, }, bd);
229		assertTrue(bd.isLeftToRight());
230		assertFalse(bd.isMixed());
231		assertFalse(bd.isRightToLeft());
232
233		bd = new Bidi(" ", Bidi.DIRECTION_RIGHT_TO_LEFT);
234		assertFalse(bd.baseIsLeftToRight());
235		assertEquals(1, bd.getBaseLevel());
236		assertEquals(1, bd.getLength());
237		assertEquals(1, bd.getLevelAt(0));
238		assertEquals(1, bd.getLevelAt(1000));
239		assertEquals(1, bd.getRunCount());
240		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, }, bd);
241		assertFalse(bd.isLeftToRight());
242		assertFalse(bd.isMixed());
243		assertTrue(bd.isRightToLeft());
244	}
245
246	public void testSimpleParagraph() {
247		bd = new Bidi("t", Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
248		assertTrue(bd.baseIsLeftToRight());
249		assertEquals(0, bd.getBaseLevel());
250		assertEquals(1, bd.getLength());
251		assertEquals(0, bd.getLevelAt(0));
252		assertEquals(0, bd.getLevelAt(1000));
253		assertEquals(1, bd.getRunCount());
254		assertRunArrayEquals(new int[][] { { 0, 1, 0 }, }, bd);
255		assertTrue(bd.isLeftToRight());
256		assertFalse(bd.isMixed());
257		assertFalse(bd.isRightToLeft());
258
259		bd = new Bidi("t", Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
260		assertTrue(bd.baseIsLeftToRight());
261		assertEquals(0, bd.getBaseLevel());
262		assertEquals(1, bd.getLength());
263		assertEquals(0, bd.getLevelAt(0));
264		assertEquals(0, bd.getLevelAt(1000));
265		assertEquals(1, bd.getRunCount());
266		assertRunArrayEquals(new int[][] { { 0, 1, 0 }, }, bd);
267		assertTrue(bd.isLeftToRight());
268		assertFalse(bd.isMixed());
269		assertFalse(bd.isRightToLeft());
270
271		bd = new Bidi("t", Bidi.DIRECTION_LEFT_TO_RIGHT);
272		assertTrue(bd.baseIsLeftToRight());
273		assertEquals(0, bd.getBaseLevel());
274		assertEquals(1, bd.getLength());
275		assertEquals(0, bd.getLevelAt(0));
276		assertEquals(0, bd.getLevelAt(1000));
277		assertEquals(1, bd.getRunCount());
278		assertRunArrayEquals(new int[][] { { 0, 1, 0 }, }, bd);
279		assertTrue(bd.isLeftToRight());
280		assertFalse(bd.isMixed());
281		assertFalse(bd.isRightToLeft());
282	}
283
284	public void testBadFlags() {
285		bd = new Bidi("", 173);
286		assertTrue(bd.baseIsLeftToRight());
287		assertEquals(0, bd.getBaseLevel());
288		assertEquals(0, bd.getLength());
289		assertEquals(0, bd.getLevelAt(0));
290		assertEquals(0, bd.getLevelAt(1000));
291		assertEquals(1, bd.getRunCount());
292		assertRunArrayEquals(new int[][] { { 0, 0, 0 }, }, bd);
293		assertTrue(bd.isLeftToRight());
294		assertFalse(bd.isMixed());
295		assertFalse(bd.isRightToLeft());
296	}
297
298	public void testBadEmbeddings() {
299		try {
300			bd = new Bidi("".toCharArray(), 0, new byte[] {}, 0, 1,
301					Bidi.DIRECTION_RIGHT_TO_LEFT);
302			fail("should throw IAE");
303		} catch (IllegalArgumentException e) {
304			// expected
305		}
306	}
307
308	public void testOverrideEmbeddings() {
309		bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) -7,
310				(byte) -2, (byte) -3 }, 0, 3,
311				Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
312		assertTrue(bd.baseIsLeftToRight());
313		assertEquals(0, bd.getBaseLevel());
314		assertEquals(3, bd.getLength());
315		assertEquals(7, bd.getLevelAt(0));
316		assertEquals(2, bd.getLevelAt(1));
317		assertEquals(3, bd.getLevelAt(2));
318		assertEquals(0, bd.getLevelAt(1000));
319		assertEquals(3, bd.getRunCount());
320		assertRunArrayEquals(new int[][] { { 0, 1, 7 }, { 1, 2, 2 },
321				{ 2, 3, 3 }, }, bd);
322		assertFalse(bd.isLeftToRight());
323		assertTrue(bd.isMixed());
324		assertFalse(bd.isRightToLeft());
325
326		bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) -1,
327				(byte) -2, (byte) -3 }, 0, 3,
328				Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
329		assertTrue(bd.baseIsLeftToRight());
330		assertEquals(0, bd.getBaseLevel());
331		assertEquals(3, bd.getLength());
332		assertEquals(1, bd.getLevelAt(0));
333		assertEquals(2, bd.getLevelAt(1));
334		assertEquals(3, bd.getLevelAt(2));
335		assertEquals(0, bd.getLevelAt(1000));
336		assertEquals(3, bd.getRunCount());
337		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
338				{ 2, 3, 3 }, }, bd);
339		assertFalse(bd.isLeftToRight());
340		assertTrue(bd.isMixed());
341		assertFalse(bd.isRightToLeft());
342
343		bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) -1,
344				(byte) -2, (byte) -3 }, 0, 3, Bidi.DIRECTION_LEFT_TO_RIGHT);
345		assertTrue(bd.baseIsLeftToRight());
346		assertEquals(0, bd.getBaseLevel());
347		assertEquals(3, bd.getLength());
348		assertEquals(1, bd.getLevelAt(0));
349		assertEquals(2, bd.getLevelAt(1));
350		assertEquals(3, bd.getLevelAt(2));
351		assertEquals(0, bd.getLevelAt(1000));
352		assertEquals(3, bd.getRunCount());
353		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
354				{ 2, 3, 3 }, }, bd);
355		assertFalse(bd.isLeftToRight());
356		assertTrue(bd.isMixed());
357		assertFalse(bd.isRightToLeft());
358
359		bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) -1,
360				(byte) -2, (byte) -3 }, 0, 3, Bidi.DIRECTION_RIGHT_TO_LEFT);
361		assertFalse(bd.baseIsLeftToRight());
362		assertEquals(1, bd.getBaseLevel());
363		assertEquals(3, bd.getLength());
364		assertEquals(1, bd.getLevelAt(0));
365		assertEquals(2, bd.getLevelAt(1));
366		assertEquals(3, bd.getLevelAt(2));
367		assertEquals(1, bd.getLevelAt(1000));
368		assertEquals(3, bd.getRunCount());
369		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
370				{ 2, 3, 3 }, }, bd);
371		assertFalse(bd.isLeftToRight());
372		assertTrue(bd.isMixed());
373		assertFalse(bd.isRightToLeft());
374	}
375
376	public void testDefaultEmbeddings() {
377		bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) 0,
378				(byte) 0, (byte) 0 }, 0, 3, Bidi.DIRECTION_RIGHT_TO_LEFT);
379		assertFalse(bd.baseIsLeftToRight());
380		assertEquals(1, bd.getBaseLevel());
381		assertEquals(3, bd.getLength());
382		assertEquals(2, bd.getLevelAt(0));
383		assertEquals(2, bd.getLevelAt(1));
384		assertEquals(2, bd.getLevelAt(2));
385		assertEquals(1, bd.getLevelAt(1000));
386		assertEquals(1, bd.getRunCount());
387		assertRunArrayEquals(new int[][] { { 0, 3, 2 }, }, bd);
388		assertFalse(bd.isLeftToRight());
389		assertTrue(bd.isMixed());
390		assertFalse(bd.isRightToLeft());
391	}
392
393	public void testRelativeEmbeddings() {
394		bd = new Bidi(new char[] { 's', 's', 's' }, 0, new byte[] { (byte) 1,
395				(byte) 2, (byte) 3 }, 0, 3, Bidi.DIRECTION_RIGHT_TO_LEFT);
396		assertFalse(bd.baseIsLeftToRight());
397		assertEquals(1, bd.getBaseLevel());
398		assertEquals(3, bd.getLength());
399		assertEquals(2, bd.getLevelAt(0));
400		assertEquals(2, bd.getLevelAt(1));
401		assertEquals(4, bd.getLevelAt(2));
402		assertEquals(1, bd.getLevelAt(1000));
403		assertEquals(2, bd.getRunCount());
404		assertRunArrayEquals(new int[][] { { 0, 2, 2 }, { 2, 3, 4 }, }, bd);
405		assertFalse(bd.isLeftToRight());
406		assertTrue(bd.isMixed());
407		assertFalse(bd.isRightToLeft());
408	}
409
410	public void testSimpleHebrewParagraph() {
411		bd = new Bidi("\u05D0", Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
412		assertFalse(bd.baseIsLeftToRight());
413		assertEquals(1, bd.getBaseLevel());
414		assertEquals(1, bd.getLength());
415		assertEquals(1, bd.getLevelAt(0));
416		assertEquals(1, bd.getLevelAt(1000));
417		assertEquals(1, bd.getRunCount());
418		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, }, bd);
419		assertFalse(bd.isLeftToRight());
420		assertFalse(bd.isMixed());
421		assertTrue(bd.isRightToLeft());
422
423		bd = new Bidi("\u05D0", Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
424		assertFalse(bd.baseIsLeftToRight());
425		assertEquals(1, bd.getBaseLevel());
426		assertEquals(1, bd.getLength());
427		assertEquals(1, bd.getLevelAt(0));
428		assertEquals(1, bd.getLevelAt(1000));
429		assertEquals(1, bd.getRunCount());
430		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, }, bd);
431		assertFalse(bd.isLeftToRight());
432		assertFalse(bd.isMixed());
433		assertTrue(bd.isRightToLeft());
434
435		bd = new Bidi("\u05D0", Bidi.DIRECTION_RIGHT_TO_LEFT);
436		assertFalse(bd.baseIsLeftToRight());
437		assertEquals(1, bd.getBaseLevel());
438		assertEquals(1, bd.getLength());
439		assertEquals(1, bd.getLevelAt(0));
440		assertEquals(1, bd.getLevelAt(1000));
441		assertEquals(1, bd.getRunCount());
442		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, }, bd);
443		assertFalse(bd.isLeftToRight());
444		assertFalse(bd.isMixed());
445		assertTrue(bd.isRightToLeft());
446	}
447
448	public void testSimpleBidiParagraph_1() {
449		bd = new Bidi("\u05D0a", Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
450		assertFalse(bd.baseIsLeftToRight());
451		assertEquals(1, bd.getBaseLevel());
452		assertEquals(2, bd.getLength());
453		assertEquals(1, bd.getLevelAt(0));
454		assertEquals(2, bd.getLevelAt(1));
455		assertEquals(1, bd.getLevelAt(1000));
456		assertEquals(2, bd.getRunCount());
457		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 }, }, bd);
458		assertFalse(bd.isLeftToRight());
459		assertTrue(bd.isMixed());
460		assertFalse(bd.isRightToLeft());
461
462		bd = new Bidi("\u05D0a", Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
463		assertFalse(bd.baseIsLeftToRight());
464		assertEquals(1, bd.getBaseLevel());
465		assertEquals(2, bd.getLength());
466		assertEquals(1, bd.getLevelAt(0));
467		assertEquals(2, bd.getLevelAt(1));
468		assertEquals(1, bd.getLevelAt(1000));
469		assertEquals(2, bd.getRunCount());
470		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 }, }, bd);
471		assertFalse(bd.isLeftToRight());
472		assertTrue(bd.isMixed());
473		assertFalse(bd.isRightToLeft());
474
475		bd = new Bidi("\u05D0a", Bidi.DIRECTION_LEFT_TO_RIGHT);
476		assertTrue(bd.baseIsLeftToRight());
477		assertEquals(0, bd.getBaseLevel());
478		assertEquals(2, bd.getLength());
479		assertEquals(1, bd.getLevelAt(0));
480		assertEquals(0, bd.getLevelAt(1));
481		assertEquals(0, bd.getLevelAt(1000));
482		assertEquals(2, bd.getRunCount());
483		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 0 }, }, bd);
484		assertFalse(bd.isLeftToRight());
485		assertTrue(bd.isMixed());
486		assertFalse(bd.isRightToLeft());
487
488		bd = new Bidi("\u05D0a", Bidi.DIRECTION_RIGHT_TO_LEFT);
489		assertFalse(bd.baseIsLeftToRight());
490		assertEquals(1, bd.getBaseLevel());
491		assertEquals(2, bd.getLength());
492		assertEquals(1, bd.getLevelAt(0));
493		assertEquals(2, bd.getLevelAt(1));
494		assertEquals(1, bd.getLevelAt(1000));
495		assertEquals(2, bd.getRunCount());
496		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 }, }, bd);
497		assertFalse(bd.isLeftToRight());
498		assertTrue(bd.isMixed());
499		assertFalse(bd.isRightToLeft());
500	}
501
502	public void testSimpleBidiParagraph_2() {
503		bd = new Bidi("a\u05D0", Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
504		assertTrue(bd.baseIsLeftToRight());
505		assertEquals(0, bd.getBaseLevel());
506		assertEquals(2, bd.getLength());
507		assertEquals(0, bd.getLevelAt(0));
508		assertEquals(1, bd.getLevelAt(1));
509		assertEquals(0, bd.getLevelAt(1000));
510		assertEquals(2, bd.getRunCount());
511		assertRunArrayEquals(new int[][] { { 0, 1, 0 }, { 1, 2, 1 }, }, bd);
512		assertFalse(bd.isLeftToRight());
513		assertTrue(bd.isMixed());
514		assertFalse(bd.isRightToLeft());
515
516		bd = new Bidi("a\u05D0", Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
517		assertTrue(bd.baseIsLeftToRight());
518		assertEquals(0, bd.getBaseLevel());
519		assertEquals(2, bd.getLength());
520		assertEquals(0, bd.getLevelAt(0));
521		assertEquals(1, bd.getLevelAt(1));
522		assertEquals(0, bd.getLevelAt(1000));
523		assertEquals(2, bd.getRunCount());
524		assertRunArrayEquals(new int[][] { { 0, 1, 0 }, { 1, 2, 1 }, }, bd);
525		assertFalse(bd.isLeftToRight());
526		assertTrue(bd.isMixed());
527		assertFalse(bd.isRightToLeft());
528
529		bd = new Bidi("a\u05D0", Bidi.DIRECTION_LEFT_TO_RIGHT);
530		assertTrue(bd.baseIsLeftToRight());
531		assertEquals(0, bd.getBaseLevel());
532		assertEquals(2, bd.getLength());
533		assertEquals(0, bd.getLevelAt(0));
534		assertEquals(1, bd.getLevelAt(1));
535		assertEquals(0, bd.getLevelAt(1000));
536		assertEquals(2, bd.getRunCount());
537		assertRunArrayEquals(new int[][] { { 0, 1, 0 }, { 1, 2, 1 }, }, bd);
538		assertFalse(bd.isLeftToRight());
539		assertTrue(bd.isMixed());
540		assertFalse(bd.isRightToLeft());
541
542		bd = new Bidi("a\u05D0", Bidi.DIRECTION_RIGHT_TO_LEFT);
543		assertFalse(bd.baseIsLeftToRight());
544		assertEquals(1, bd.getBaseLevel());
545		assertEquals(2, bd.getLength());
546		assertEquals(2, bd.getLevelAt(0));
547		assertEquals(1, bd.getLevelAt(1));
548		assertEquals(1, bd.getLevelAt(1000));
549		assertEquals(2, bd.getRunCount());
550		assertRunArrayEquals(new int[][] { { 0, 1, 2 }, { 1, 2, 1 }, }, bd);
551		assertFalse(bd.isLeftToRight());
552		assertTrue(bd.isMixed());
553		assertFalse(bd.isRightToLeft());
554	}
555
556	/*
557	 * spec reads: public static final int DIRECTION_RIGHT_TO_LEFT Constant
558	 * indicating base direction is right-to-left. according to that, the method
559	 * baseIsLeftToRight() here should return false. however, RI doesn't act so.
560	 */
561	public void testRIBug_1() {
562		bd = new Bidi("t", Bidi.DIRECTION_RIGHT_TO_LEFT);
563		assertFalse(bd.baseIsLeftToRight());
564		// the base level it the essential cause
565		assertEquals(1, bd.getBaseLevel());
566		assertEquals(1, bd.getLength());
567		assertEquals(2, bd.getLevelAt(0));
568		assertEquals(1, bd.getLevelAt(1000));
569		assertEquals(1, bd.getRunCount());
570		assertRunArrayEquals(new int[][] { { 0, 1, 2 }, }, bd);
571		assertFalse(bd.isLeftToRight());
572		assertTrue(bd.isMixed());
573		assertFalse(bd.isRightToLeft());
574	}
575
576	// this is essentially the same bug as Bug_1
577	public void testRIBug_2() {
578		bd = new Bidi("\u05D0", Bidi.DIRECTION_LEFT_TO_RIGHT);
579		assertTrue(bd.baseIsLeftToRight());
580		assertEquals(0, bd.getBaseLevel());
581		assertEquals(1, bd.getLength());
582		assertEquals(1, bd.getLevelAt(0));
583		assertEquals(0, bd.getLevelAt(1000));
584		assertEquals(1, bd.getRunCount());
585		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, }, bd);
586		assertFalse(bd.isLeftToRight());
587		assertTrue(bd.isMixed());
588		assertFalse(bd.isRightToLeft());
589	}
590
591	public void testComplicatedBidi() {
592		bd = new Bidi("a\u05D0a\"a\u05D0\"\u05D0a",
593				Bidi.DIRECTION_RIGHT_TO_LEFT);
594		assertFalse(bd.baseIsLeftToRight());
595		assertEquals(1, bd.getBaseLevel());
596		assertEquals(9, bd.getLength());
597		assertEquals(2, bd.getLevelAt(0));
598		assertEquals(1, bd.getLevelAt(1));
599		assertEquals(2, bd.getLevelAt(2));
600		assertEquals(2, bd.getLevelAt(3));
601		assertEquals(2, bd.getLevelAt(4));
602		assertEquals(1, bd.getLevelAt(5));
603		assertEquals(1, bd.getLevelAt(6));
604		assertEquals(1, bd.getLevelAt(7));
605		assertEquals(2, bd.getLevelAt(8));
606		assertEquals(1, bd.getLevelAt(1000));
607		assertEquals(5, bd.getRunCount());
608		assertRunArrayEquals(new int[][] { { 0, 1, 2 }, { 1, 2, 1 },
609				{ 2, 5, 2 }, { 5, 8, 1 }, { 8, 9, 2 }, }, bd);
610		assertFalse(bd.isLeftToRight());
611		assertTrue(bd.isMixed());
612		assertFalse(bd.isRightToLeft());
613	}
614
615	public void testComplicatedOverrideBidi() {
616		bd = new Bidi("a\u05D0a\"a\u05D0\"\u05D0a".toCharArray(), 0,
617				new byte[] { 0, 0, 0, -3, -3, 2, 2, 0, 3 }, 0, 9,
618				Bidi.DIRECTION_RIGHT_TO_LEFT);
619		assertFalse(bd.baseIsLeftToRight());
620		assertEquals(1, bd.getBaseLevel());
621		assertEquals(9, bd.getLength());
622		assertEquals(2, bd.getLevelAt(0));
623		assertEquals(1, bd.getLevelAt(1));
624		assertEquals(2, bd.getLevelAt(2));
625		assertEquals(3, bd.getLevelAt(3));
626		assertEquals(3, bd.getLevelAt(4));
627		assertEquals(3, bd.getLevelAt(5));
628		assertEquals(2, bd.getLevelAt(6));
629		assertEquals(1, bd.getLevelAt(7));
630		assertEquals(4, bd.getLevelAt(8));
631		assertEquals(1, bd.getLevelAt(1000));
632		assertEquals(7, bd.getRunCount());
633		assertRunArrayEquals(new int[][] { { 0, 1, 2 }, { 1, 2, 1 },
634				{ 2, 3, 2 }, { 3, 6, 3 }, { 6, 7, 2 }, { 7, 8, 1 },
635				{ 8, 9, 4 }, }, bd);
636		assertFalse(bd.isLeftToRight());
637		assertTrue(bd.isMixed());
638		assertFalse(bd.isRightToLeft());
639	}
640
641	public void testRequiresBidi() {
642		try{
643		    Bidi.requiresBidi(null, 0, 0);
644		    fail("should throw NullPointerException");
645        }catch (NullPointerException e){
646            // expected
647        }
648
649		try {
650			assertFalse(Bidi.requiresBidi(null, 0, 1));
651			fail("should throw NPE");
652		} catch (NullPointerException e) {
653			// expected
654		}
655		try {
656			assertFalse(Bidi.requiresBidi("".toCharArray(), 0, 1));
657			fail("should throw IllegalArgumentException");
658		} catch (IllegalArgumentException e) {
659			// expected
660		}
661		try {
662			assertFalse(Bidi.requiresBidi("aaa".toCharArray(), -1, 1));
663			fail("should throw IllegalArgumentException");
664		} catch (IllegalArgumentException e) {
665			// expected
666		}
667        try {
668            assertFalse(Bidi.requiresBidi("aaa".toCharArray(), 1, -1));
669            fail("should throw IllegalArgumentException");
670        } catch (IllegalArgumentException e) {
671            // expected
672        }
673        try {
674            assertFalse(Bidi.requiresBidi("\u05D0".toCharArray(), 1, -1));
675            fail("should throw IllegalArgumentException");
676        } catch (IllegalArgumentException e) {
677            // expected
678        }
679        try {
680            assertFalse(Bidi.requiresBidi("aaa".toCharArray(), 1, 0));
681            fail("should throw IllegalArgumentException");
682        } catch (IllegalArgumentException e) {
683            // expected
684        }
685        try {
686            assertFalse(Bidi.requiresBidi("aaa".toCharArray(), 7, 7));
687            fail("should throw IllegalArgumentException");
688        } catch (IllegalArgumentException e) {
689            // expected
690        }
691        try {
692            assertFalse(Bidi.requiresBidi("aaa".toCharArray(), 1, Integer.MAX_VALUE));
693            fail("should throw IllegalArgumentException");
694        } catch (IllegalArgumentException e) {
695            // expected
696        }
697        try {
698            assertFalse(Bidi.requiresBidi("aaa".toCharArray(), Integer.MAX_VALUE, 1));
699            fail("should throw IllegalArgumentException");
700        } catch (IllegalArgumentException e) {
701            // expected
702        }
703
704        assertFalse(Bidi.requiresBidi("".toCharArray(), 0, 0));
705        assertFalse(Bidi.requiresBidi("aaa".toCharArray(), 1, 1));
706        assertFalse(Bidi.requiresBidi("aaa".toCharArray(), 0, 2));
707		assertFalse(Bidi.requiresBidi("\u05D0".toCharArray(), 1, 1));
708		assertTrue(Bidi.requiresBidi("\u05D0".toCharArray(), 0, 1));
709		assertFalse(Bidi.requiresBidi("aa\u05D0a".toCharArray(), 0, 2));
710		assertTrue(Bidi.requiresBidi("aa\u05D0a".toCharArray(), 1, 3));
711	}
712
713	public void testHebrewOverrideEmbeddings() {
714		bd = new Bidi(new char[] { '\u05D0', '\u05D0', '\u05D0' }, 0,
715				new byte[] { (byte) -1, (byte) -2, (byte) -3 }, 0, 3,
716				Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
717		assertFalse(bd.baseIsLeftToRight());
718		assertEquals(1, bd.getBaseLevel());
719		assertEquals(3, bd.getLength());
720		assertEquals(1, bd.getLevelAt(0));
721		assertEquals(2, bd.getLevelAt(1));
722		assertEquals(3, bd.getLevelAt(2));
723		assertEquals(1, bd.getLevelAt(1000));
724		assertEquals(3, bd.getRunCount());
725		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
726				{ 2, 3, 3 }, }, bd);
727		assertFalse(bd.isLeftToRight());
728		assertTrue(bd.isMixed());
729		assertFalse(bd.isRightToLeft());
730
731		bd = new Bidi(new char[] { '\u05D0', '\u05D0', '\u05D0' }, 0,
732				new byte[] { (byte) -1, (byte) -2, (byte) -3 }, 0, 3,
733				Bidi.DIRECTION_DEFAULT_RIGHT_TO_LEFT);
734		assertFalse(bd.baseIsLeftToRight());
735		assertEquals(1, bd.getBaseLevel());
736		assertEquals(3, bd.getLength());
737		assertEquals(1, bd.getLevelAt(0));
738		assertEquals(2, bd.getLevelAt(1));
739		assertEquals(3, bd.getLevelAt(2));
740		assertEquals(1, bd.getLevelAt(1000));
741		assertEquals(3, bd.getRunCount());
742		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
743				{ 2, 3, 3 }, }, bd);
744		assertFalse(bd.isLeftToRight());
745		assertTrue(bd.isMixed());
746		assertFalse(bd.isRightToLeft());
747
748		bd = new Bidi(new char[] { '\u05D0', '\u05D0', '\u05D0' }, 0,
749				new byte[] { (byte) -1, (byte) -2, (byte) -3 }, 0, 3,
750				Bidi.DIRECTION_LEFT_TO_RIGHT);
751		assertTrue(bd.baseIsLeftToRight());
752		assertEquals(0, bd.getBaseLevel());
753		assertEquals(3, bd.getLength());
754		assertEquals(1, bd.getLevelAt(0));
755		assertEquals(2, bd.getLevelAt(1));
756		assertEquals(3, bd.getLevelAt(2));
757		assertEquals(0, bd.getLevelAt(1000));
758		assertEquals(3, bd.getRunCount());
759		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
760				{ 2, 3, 3 }, }, bd);
761		assertFalse(bd.isLeftToRight());
762		assertTrue(bd.isMixed());
763		assertFalse(bd.isRightToLeft());
764
765		bd = new Bidi(new char[] { '\u05D0', '\u05D0', '\u05D0' }, 0,
766				new byte[] { (byte) -1, (byte) -2, (byte) -3 }, 0, 3,
767				Bidi.DIRECTION_RIGHT_TO_LEFT);
768		assertFalse(bd.baseIsLeftToRight());
769		assertEquals(1, bd.getBaseLevel());
770		assertEquals(3, bd.getLength());
771		assertEquals(1, bd.getLevelAt(0));
772		assertEquals(2, bd.getLevelAt(1));
773		assertEquals(3, bd.getLevelAt(2));
774		assertEquals(1, bd.getLevelAt(1000));
775		assertEquals(3, bd.getRunCount());
776		assertRunArrayEquals(new int[][] { { 0, 1, 1 }, { 1, 2, 2 },
777				{ 2, 3, 3 }, }, bd);
778		assertFalse(bd.isLeftToRight());
779		assertTrue(bd.isMixed());
780		assertFalse(bd.isRightToLeft());
781	}
782
783	public void testCreateLineBidi() {
784		bd = new Bidi("a\u05D0a\u05D0a\u05D0\"\u05D0a".toCharArray(), 0,
785				new byte[] { 0, 0, 0, -3, -3, 2, 2, 0, 3 }, 0, 9,
786				Bidi.DIRECTION_RIGHT_TO_LEFT);
787		Bidi line = bd.createLineBidi(2, 7);
788		assertFalse(line.baseIsLeftToRight());
789		assertEquals(1, line.getBaseLevel());
790		assertEquals(5, line.getLength());
791		assertEquals(2, line.getLevelAt(0));
792		assertEquals(3, line.getLevelAt(1));
793		assertEquals(3, line.getLevelAt(2));
794		assertEquals(3, line.getLevelAt(3));
795		assertEquals(2, line.getLevelAt(4));
796		assertEquals(1, line.getLevelAt(1000));
797		assertEquals(3, line.getRunCount());
798		assertRunArrayEquals(new int[][] { { 0, 1, 2 }, { 1, 4, 3 },
799				{ 4, 5, 2 }, }, line);
800		assertFalse(line.isLeftToRight());
801		assertTrue(line.isMixed());
802		assertFalse(line.isRightToLeft());
803	}
804
805    public void testCreateLineBidiInvalid() {
806        //regression for HARMONY-1050
807        Bidi bidi = new Bidi("str", 1);
808        try {
809            bidi.createLineBidi(-1, 1);
810            fail("Expected IAE");
811        } catch (IllegalArgumentException e) {
812            // Expected
813        }
814
815        try {
816            bidi.createLineBidi(1, -1);
817            fail("Expected IAE");
818        } catch (IllegalArgumentException e) {
819            // Expected
820        }
821
822        try {
823            bidi.createLineBidi(-1, -1);
824            fail("Expected IAE");
825        } catch (IllegalArgumentException e) {
826            // Expected
827        }
828
829        try {
830            bidi.createLineBidi(2, 1);
831            fail("Expected IAE");
832        } catch (IllegalArgumentException e) {
833            // Expected
834        }
835
836        try {
837            bidi.createLineBidi(2, 2);
838        }catch (IllegalArgumentException e){
839            // Expected
840        }
841
842        try {
843            bidi.createLineBidi(2, 4);
844            fail("Expected IAE");
845        } catch (IllegalArgumentException e) {
846            // Expected
847        }
848    }
849
850	public void testIncompatibleLineAlgorithm() {
851		// ICU treat a new line as in the same run, however RI does not
852		bd = new Bidi("aaaaa".toCharArray(), 0,
853				new byte[] { -2, -1, -3, -3, -2 }, 0, 5,
854				Bidi.DIRECTION_RIGHT_TO_LEFT);
855		Bidi line = bd.createLineBidi(1, 4);
856		assertFalse(line.baseIsLeftToRight());
857		assertEquals(1, line.getBaseLevel());
858		assertEquals(3, line.getLength());
859		assertEquals(1, line.getLevelAt(0));
860		assertEquals(1, line.getLevelAt(1));
861		assertEquals(1, line.getLevelAt(2));
862		assertEquals(1, line.getLevelAt(1000));
863		assertEquals(1, line.getRunCount());
864		assertRunArrayEquals(new int[][] { { 0, 3, 1 }, }, line);
865		assertFalse(line.isLeftToRight());
866		assertFalse(line.isMixed());
867		assertTrue(line.isRightToLeft());
868	}
869
870	public void testReorderVisually() {
871		String[] init = new String[] { "a", "b", "c", "d" };
872		String[] s = new String[4];
873
874		System.arraycopy(init, 0, s, 0, s.length);
875		Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, 0, s, 0, 4);
876		assertEquals("[c, b, a, d]", Arrays.asList(s).toString());
877
878		System.arraycopy(init, 0, s, 0, s.length);
879		Bidi.reorderVisually(new byte[] { 1, 3 }, 0, s, 1, 2);
880		assertEquals("[a, c, b, d]", Arrays.asList(s).toString());
881
882		System.arraycopy(init, 0, s, 0, s.length);
883		Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, 1, s, 1, 2);
884		assertEquals("[a, c, b, d]", Arrays.asList(s).toString());
885
886		System.arraycopy(init, 0, s, 0, s.length);
887		Bidi.reorderVisually(new byte[] { 2, 1, 2, 1 }, 1, s, 0, 3);
888		assertEquals("[c, b, a, d]", Arrays.asList(s).toString());
889
890		System.arraycopy(init, 0, s, 0, s.length);
891		Bidi.reorderVisually(new byte[] { 2, 1, 0, 1 }, 1, s, 0, 3);
892		assertEquals("[a, b, c, d]", Arrays.asList(s).toString());
893	}
894
895	public void testBadReorderVisually() {
896		String[] s = new String[] { "a", "b", "c", "d" };
897
898		try {
899			Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, 0, s, 0, 5);
900			fail("should throw IAE");
901		} catch (IllegalArgumentException e) {
902			// expected
903		}
904
905		try {
906			Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, 0, s, -1, 1);
907			fail("should throw IAE");
908		} catch (IllegalArgumentException e) {
909			// expected
910		}
911
912		try {
913			Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, -1, s, 0, 1);
914			fail("should throw IAE");
915		} catch (IllegalArgumentException e) {
916			// expected
917		}
918
919		try {
920			Bidi.reorderVisually(null, 0, s, 0, 1);
921			fail("should throw NPE");
922		} catch (NullPointerException e) {
923			// expected
924		}
925
926		try {
927			Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, 0, null, 0, 1);
928			fail("should throw NPE");
929		} catch (NullPointerException e) {
930			// expected
931		}
932
933        try {
934            Bidi.reorderVisually(new byte[] { 2, 1, 3, 0 }, 1, s, 0, -1);
935            fail("should throw IAE");
936        } catch (IllegalArgumentException e) {
937            // expected
938        }
939
940	}
941
942    public void testGetRuns() {
943        //Regression test for Harmony-1028
944
945        String LTR = "\u0061\u0062";
946        String RTL = "\u05DC\u05DD";
947        String newLine = "\n";
948        String defText = LTR + newLine + RTL + LTR + RTL;
949
950        int[][] expectedRuns = {
951                {0, 3},
952                {3, 5},
953                {5, 7},
954                {7, 9},
955        };
956
957        Bidi bi = new Bidi(defText, 0);
958        final int count = bi.getRunCount();
959        for (int i = 0; i < count; i++) {
960            assertEquals(expectedRuns[i][0], bi.getRunStart(i));
961            assertEquals(expectedRuns[i][1], bi.getRunLimit(i));
962        }
963    }
964       public void testGetRunLimit() {
965         bd = new Bidi("text", Bidi.DIRECTION_LEFT_TO_RIGHT);
966         try {
967             assertTrue(4 == bd.getRunLimit(-1));
968         } catch (IllegalArgumentException e) {
969             // Expected for illegal run limit
970             return;
971         }
972
973         fail("Expected IllegalArgumentException to be thrown for invalid run limit");
974       }
975
976       public void testBidiConstructor_Iterator() {
977               AttributedString paragraph = new AttributedString("text");
978         bd = new Bidi(paragraph.getIterator());
979         try {
980             assertTrue(4 == bd.getRunLimit(1));
981         } catch (IllegalArgumentException e) {
982             // Expected for illegal run limit
983             return;
984         }
985
986         fail("Expected IllegalArgumentException to be thrown for invalid run limit");
987       }
988
989}
990