]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/richtext/test/TestTextPanel.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / richtext / test / TestTextPanel.java
1 /*\r
2  * (C) Copyright IBM Corp. 1998-2007.  All Rights Reserved.\r
3  *\r
4  * The program is provided "as is" without any warranty express or\r
5  * implied, including the warranty of non-infringement and the implied\r
6  * warranties of merchantibility and fitness for a particular purpose.\r
7  * IBM will not be liable for any damages suffered by you as a result\r
8  * of using the Program. In no event will IBM be liable for any\r
9  * special, indirect or consequential damages or lost profits even if\r
10  * IBM has been advised of the possibility of their occurrence. IBM\r
11  * will not be liable for any third party claims against you.\r
12  */\r
13 \r
14 package com.ibm.richtext.test;\r
15 \r
16 import java.util.Random;\r
17 import java.awt.Color;\r
18 import java.awt.Frame;\r
19 import java.awt.event.KeyEvent;\r
20 \r
21 import java.awt.datatransfer.Clipboard;\r
22 import java.awt.datatransfer.ClipboardOwner;\r
23 import java.awt.datatransfer.StringSelection;\r
24 import java.awt.datatransfer.Transferable;\r
25 \r
26 import com.ibm.richtext.textpanel.KeyRemap;\r
27 import com.ibm.richtext.textpanel.KeyEventForwarder;\r
28 import com.ibm.richtext.textpanel.MTextPanel;\r
29 import com.ibm.richtext.textpanel.TextPanel;\r
30 import com.ibm.richtext.textpanel.TextPanelEvent;\r
31 import com.ibm.richtext.textpanel.TextPanelListener;\r
32 \r
33 import com.ibm.richtext.styledtext.MConstText;\r
34 import com.ibm.richtext.styledtext.StyledText;\r
35 import com.ibm.richtext.textlayout.attributes.TextAttribute;\r
36 import com.ibm.richtext.textlayout.attributes.AttributeMap;\r
37 \r
38 import com.ibm.richtext.styledtext.StyleModifier;\r
39 import com.ibm.richtext.textlayout.attributes.AttributeSet;\r
40 \r
41 // Note:  this used to be a TestFmwk test.  If you add\r
42 // more tests to it, be sure to add them to \r
43 // com.ibm.richtext.test.unit.FmwkTestTextPanel.test() -\r
44 // otherwise they won't get run!\r
45 \r
46 public class TestTextPanel /*extends TestFmwk*/ {\r
47 \r
48     private final class TestListener implements TextPanelListener {\r
49         \r
50         private int NO_WAY = 0;\r
51         private int DEFINITELY = 1;\r
52         private int MAYBE = 2;\r
53         \r
54         private final int[] status;\r
55         \r
56         TestListener(MTextPanel textPanel) {\r
57             \r
58             int length = TextPanelEvent.TEXT_PANEL_LAST -\r
59                          TextPanelEvent.TEXT_PANEL_FIRST + 1;\r
60             status = new int[length];\r
61             textPanel.addListener(this);\r
62             allowAll();\r
63         }\r
64         \r
65         void refuseAll() {\r
66             \r
67             for (int i=0; i < status.length; i++) {\r
68                 status[i] = NO_WAY;\r
69             }\r
70         }\r
71         \r
72         void allowAll() {\r
73             \r
74             for (int i=0; i < status.length; i++) {\r
75                 status[i] = MAYBE;\r
76             }\r
77         }\r
78         \r
79         void expectEvent(int type) {\r
80             \r
81             int index = type - TextPanelEvent.TEXT_PANEL_FIRST;\r
82             status[index] = DEFINITELY;\r
83         }\r
84         \r
85         void allowEvent(int type) {\r
86             int index = type - TextPanelEvent.TEXT_PANEL_FIRST;\r
87             status[index] = MAYBE;\r
88         }\r
89         \r
90         void assertNotExpectingEvents() {\r
91             assertNotExpectingEvents(false, 0, false);\r
92         }\r
93         \r
94         void assertNotExpectingEvents(int iterCount, boolean exp) {\r
95             assertNotExpectingEvents(true, iterCount, exp);\r
96         }\r
97         \r
98         private void assertNotExpectingEvents(boolean logDetails, int iterCount, boolean exp) {\r
99             \r
100             boolean e = false;\r
101             for (int i=0; i < status.length; i++) {\r
102                 if (status[i] == DEFINITELY) {\r
103                     if (logDetails) {\r
104                         logMessage("Expecting event " +\r
105                                         (i+TextPanelEvent.TEXT_PANEL_FIRST));\r
106                         logMessage("iterationCount="+iterCount+";  expexting="+exp);\r
107                     }\r
108                     e = true;\r
109                 }\r
110             }\r
111             if (e) {\r
112                 reportError("Some events pending");\r
113             }\r
114         }\r
115         \r
116         public void textEventOccurred(TextPanelEvent event) {\r
117             \r
118             int index = event.getID() - TextPanelEvent.TEXT_PANEL_FIRST;\r
119             if (status[index] == NO_WAY) {\r
120                 reportError("Unexpected event: " + event);\r
121             }\r
122             else if (status[index] == DEFINITELY) {\r
123                 status[index] = NO_WAY;\r
124             }\r
125         }\r
126         \r
127         public boolean respondsToEventType(int type) {\r
128             \r
129             return true;\r
130         }\r
131     }\r
132 \r
133     static final String COPYRIGHT =\r
134                 "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";\r
135 \r
136     private static final String STRING_CONTENT = "Some content";\r
137     private static final int TEST_ITERS = 2;\r
138     public static final MConstText MOD_TEXT =\r
139                 new StyledText("Styled", AttributeMap.EMPTY_ATTRIBUTE_MAP);\r
140 \r
141     private Clipboard fClipboard;\r
142     private MTextPanel fTextPanel = null;\r
143     private TestListener fListener = null;\r
144     private int fRandSeed = 0;\r
145     private Random rand;\r
146     \r
147     private static final int BIG_COMMAND_LOG_SIZE = 40;\r
148     private static final int SMALL_COMMAND_LOG_SIZE = 8;\r
149 \r
150     private static final StyleModifier[] paraMods = {\r
151         StyleModifier.createAddModifier(\r
152                 new AttributeMap(TextAttribute.LINE_FLUSH,\r
153                                  TextAttribute.FLUSH_LEADING)),\r
154         StyleModifier.createAddModifier(TextAttribute.LINE_FLUSH,\r
155                                  TextAttribute.FLUSH_CENTER),\r
156         StyleModifier.createAddModifier(TextAttribute.LINE_FLUSH,\r
157                                  TextAttribute.FLUSH_TRAILING),\r
158         StyleModifier.createAddModifier(TextAttribute.LINE_FLUSH,\r
159                                  TextAttribute.FULLY_JUSTIFIED),\r
160         StyleModifier.createAddModifier(TextAttribute.RUN_DIRECTION,\r
161                                  TextAttribute.RUN_DIRECTION_RTL),\r
162         StyleModifier.createAddModifier(TextAttribute.RUN_DIRECTION,\r
163                                  TextAttribute.RUN_DIRECTION_LTR),\r
164         StyleModifier.createRemoveModifier(\r
165                 new AttributeSet(TextAttribute.LINE_FLUSH)),\r
166         StyleModifier.createRemoveModifier(\r
167                 new AttributeSet(TextAttribute.RUN_DIRECTION))\r
168     };\r
169 \r
170     private static final int SELECT = 0;\r
171     private static final int SET_CARET_POS = 1;\r
172     private static final int SET_START = 2;\r
173     private static final int SET_END = 3;\r
174 \r
175     // using both styles of add modifier: AttributeMap and\r
176     // key-value, just for variety...\r
177     private static final StyleModifier[] charMods = {\r
178         StyleModifier.createAddModifier(\r
179                 new AttributeMap(TextAttribute.WEIGHT,\r
180                                  TextAttribute.WEIGHT_BOLD)),\r
181         StyleModifier.createAddModifier(TextAttribute.FOREGROUND,\r
182                                  Color.green),\r
183         StyleModifier.createAddModifier(\r
184                 new AttributeMap(TextAttribute.UNDERLINE,\r
185                                  TextAttribute.UNDERLINE_ON).addAttributes(\r
186                 new AttributeMap(TextAttribute.SIZE, new Float(6)))),\r
187         StyleModifier.createReplaceModifier(\r
188                 new AttributeMap(TextAttribute.FAMILY, "Dialog")),\r
189         StyleModifier.createRemoveModifier(\r
190                 new AttributeSet(\r
191                 new Object[] { TextAttribute.WEIGHT,\r
192                            TextAttribute.POSTURE,\r
193                            TextAttribute.UNDERLINE,\r
194                            TextAttribute.STRIKETHROUGH,\r
195                            TextAttribute.SUPERSCRIPT })),\r
196         StyleModifier.IDENTITY\r
197     };\r
198 \r
199     private static final char[] TYPED_CHARS = new char[128 - ' ' + 3];\r
200     static {\r
201         TYPED_CHARS[0] = 8; // backspace\r
202         TYPED_CHARS[1] = '\t';\r
203         TYPED_CHARS[2] = '\n';\r
204         for (int i=3; i < TYPED_CHARS.length; i++) {\r
205             TYPED_CHARS[i] = (char) (' ' + i - 3);\r
206         }\r
207     }\r
208 \r
209     public TestTextPanel() {\r
210 \r
211         fClipboard = new Clipboard("TestTextPanel");\r
212         incRandSeed();\r
213     }\r
214 \r
215     protected void reportError(String message) {\r
216     \r
217         System.err.println(message);\r
218         throw new RuntimeException(message);\r
219         //super.errln(message);\r
220     }\r
221     \r
222     protected void logMessage(String message) {\r
223     \r
224         System.err.println(message);\r
225         //super.logMessage(message);\r
226     }\r
227     \r
228     public TestTextPanel(MTextPanel panel) {\r
229         \r
230         this();\r
231         setTextPanel(panel);\r
232     }\r
233     \r
234     void incRandSeed() {\r
235         \r
236         rand = new Random(++fRandSeed);\r
237     }\r
238     \r
239     int getRandSeed() {\r
240         \r
241         return fRandSeed;\r
242     }\r
243 \r
244     int randInt(int limit) {\r
245 \r
246         return randInt(0, limit);\r
247     }\r
248 \r
249     int randInt(int start, int limit) {\r
250 \r
251         if (start > limit) {\r
252             throw new IllegalArgumentException("Range is 0-length.");\r
253         }\r
254         else if (start == limit) {\r
255             return start;\r
256         }\r
257 \r
258         return start + (Math.abs(rand.nextInt())%(limit-start)) ;\r
259     }\r
260 \r
261     public void test() {\r
262 \r
263         AttributeMap bold = new AttributeMap(TextAttribute.WEIGHT,\r
264                                              TextAttribute.WEIGHT_BOLD);\r
265         MConstText text1 = new StyledText("Test contents. 1234\nHow about it?",\r
266                                               AttributeMap.EMPTY_ATTRIBUTE_MAP);\r
267         MConstText text2 = new StyledText("Another test string.", bold);\r
268 \r
269         _testWithText(text1);\r
270         _testWithText(text2);\r
271         _testWithText(new StyledText());\r
272 \r
273         StyledText big1 = new StyledText();\r
274         for (int i=0; i < 50; i++) {\r
275             big1.append(text1);\r
276         }\r
277 \r
278         _testWithText(big1);\r
279         StyledText big2 = new StyledText(text1);\r
280         for (int i=0; i < 80; i++) {\r
281             big2.append(text2);\r
282         }\r
283 \r
284         _testWithText(big2);\r
285     }\r
286     \r
287     private void setTextPanel(MTextPanel panel) {\r
288         \r
289         fTextPanel = panel;\r
290         fListener = new TestListener(panel);\r
291     }\r
292     \r
293     private void _testWithText(MConstText text) {\r
294 \r
295         setTextPanel(new TextPanel(text, fClipboard));\r
296 \r
297         for (int i=0; i < TEST_ITERS; i++) {\r
298             _testSetSelection();\r
299             _testModifications(MOD_TEXT, true);\r
300             _testEditMenuOperations(fClipboard);\r
301             _testModFlag(fTextPanel.getCommandLogSize());\r
302             _testCommandLogControl();\r
303         }\r
304     }\r
305 \r
306     private void _testSelection(int function, \r
307                                final int aStart,\r
308                                final int aLimit) {\r
309 \r
310         int oldStart = fTextPanel.getSelectionStart();\r
311         int oldLimit = fTextPanel.getSelectionEnd();\r
312 \r
313         final int length = fTextPanel.getTextLength();\r
314         \r
315         int start = aStart;\r
316         int limit = aLimit;\r
317         \r
318         if (start < 0) {\r
319             start = 0;\r
320         }\r
321         else if (start > length) {\r
322             start = length;\r
323         }\r
324 \r
325         if (limit < start) {\r
326             limit = start;\r
327         }\r
328         else if (limit > length) {\r
329             limit = length;\r
330         }\r
331         \r
332         fListener.refuseAll();\r
333         \r
334         if (oldStart != start || oldLimit != limit) {\r
335             fListener.expectEvent(TextPanelEvent.SELECTION_RANGE_CHANGED);\r
336             fListener.allowEvent(TextPanelEvent.SELECTION_STYLES_CHANGED);\r
337         }\r
338         if ((oldStart==oldLimit) != (start==limit)) {\r
339             fListener.expectEvent(TextPanelEvent.SELECTION_EMPTY_CHANGED);\r
340         }\r
341         if (oldStart==oldLimit) {\r
342             fListener.allowEvent(TextPanelEvent.UNDO_STATE_CHANGED);\r
343         }\r
344 \r
345         switch(function) {\r
346             case SELECT:\r
347                 fTextPanel.select(aStart, aLimit);\r
348                 break;\r
349             case SET_CARET_POS:\r
350                 fTextPanel.setCaretPosition(aStart);\r
351                 break;\r
352             case SET_START:\r
353                 fTextPanel.setSelectionStart(aStart);\r
354                 break;\r
355             case SET_END:\r
356                 fTextPanel.setSelectionEnd(aLimit);\r
357                 break;\r
358             default:\r
359                 throw new IllegalArgumentException("Invalid function");\r
360         }\r
361         \r
362         if (fTextPanel.getSelectionStart() != start) {\r
363             reportError("getSelectionStart is incorrect after set");\r
364         }\r
365         if (fTextPanel.getSelectionEnd() != limit) {\r
366             reportError("getSelectionEnd is incorrect after set");\r
367         }\r
368         fListener.assertNotExpectingEvents();\r
369         fListener.allowAll();\r
370     }\r
371 \r
372     private void setAndTestSelection(int start, int limit) {\r
373         \r
374         _testSelection(SELECT, start, limit);\r
375     }\r
376 \r
377     private void setAndTestCaret(int caretPos) {\r
378 \r
379         _testSelection(SET_CARET_POS, caretPos, caretPos);\r
380     }\r
381 \r
382     private void setAndTestSelectionStart(int selStart) {\r
383 \r
384         int limit = fTextPanel.getSelectionEnd();\r
385         _testSelection(SET_START, selStart, limit);\r
386     }\r
387 \r
388     private void setAndTestSelectionEnd(int selEnd) {\r
389 \r
390         int start = fTextPanel.getSelectionStart();\r
391         _testSelection(SET_END, start, selEnd);\r
392     }\r
393 \r
394     public void _testSetSelection() {\r
395 \r
396         int textLength = fTextPanel.getTextLength();\r
397         if (textLength != fTextPanel.getText().length()) {\r
398             reportError("Text panel length is not correct");\r
399         }\r
400 \r
401         setAndTestSelection(0, textLength / 2);\r
402         setAndTestSelection(textLength / 2, textLength);\r
403         setAndTestSelection(0, textLength);\r
404         setAndTestSelection(-1, textLength+1);\r
405         if (textLength > 0) {\r
406             setAndTestSelection(0, textLength - 1);\r
407             setAndTestSelection(0, 1);\r
408         }\r
409 \r
410         final int incAmount = Math.max(1, textLength/5);\r
411         for (int index = 0; index <= textLength; index += incAmount) {\r
412 \r
413             setAndTestCaret(index);\r
414             setAndTestSelectionStart(textLength-index);\r
415             setAndTestSelectionEnd(textLength);\r
416             setAndTestSelectionStart(0);\r
417             setAndTestSelectionEnd(textLength-index);\r
418         }\r
419     }\r
420 \r
421     /**\r
422      * Text must be editable to pass this test.\r
423      */\r
424     public void _testModifications(MConstText insertionText,\r
425                                    boolean restoreOldText) {\r
426 \r
427         MConstText oldText = new StyledText(fTextPanel.getText());\r
428         final int insLength = insertionText.length();\r
429 \r
430         fListener.allowAll();\r
431         fListener.expectEvent(TextPanelEvent.TEXT_CHANGED);\r
432         fListener.expectEvent(TextPanelEvent.SELECTION_RANGE_CHANGED);\r
433         fTextPanel.append(insertionText);\r
434         fListener.assertNotExpectingEvents();\r
435         \r
436         if (fTextPanel.getSelectionStart() != oldText.length() + insLength) {\r
437             reportError("Append didn't result in correct selection");\r
438         }\r
439 \r
440         fListener.expectEvent(TextPanelEvent.TEXT_CHANGED);\r
441         fListener.expectEvent(TextPanelEvent.SELECTION_RANGE_CHANGED);\r
442         fTextPanel.insert(insertionText, 0);\r
443         fListener.assertNotExpectingEvents();\r
444         fListener.allowAll();\r
445         \r
446         if (fTextPanel.getSelectionStart() != insLength) {\r
447             reportError("Insert didn't result in correct selection");\r
448         }\r
449 \r
450         fTextPanel.replaceRange(insertionText, insLength, insLength+oldText.length());\r
451         if (fTextPanel.getSelectionStart() != insLength*2) {\r
452             reportError("Replace didn't result in correct selection");\r
453         }\r
454         if (fTextPanel.getSelectionEnd() != insLength*2) {\r
455             reportError("Replace didn't result in correct selection");\r
456         }\r
457         if (fTextPanel.getTextLength() != insLength*3) {\r
458             reportError("textLength is incorrect");\r
459         }\r
460 \r
461         if (restoreOldText) {\r
462             fTextPanel.setText(oldText);\r
463             if (fTextPanel.getSelectionStart() != oldText.length()) {\r
464                 reportError("setText didn't result in correct selection");\r
465             }\r
466             if (fTextPanel.getTextLength() != oldText.length()) {\r
467                 reportError("length incorrect after setText");\r
468             }\r
469         }\r
470         \r
471         fListener.allowAll();\r
472     }\r
473 \r
474     private static int iterationCount = 0;\r
475     public void _testCommandLogControl() {\r
476 \r
477         fListener.refuseAll();\r
478         iterationCount++;\r
479         boolean exp = false;\r
480         if (fTextPanel.canRedo() || BIG_COMMAND_LOG_SIZE==0) {\r
481             fListener.expectEvent(TextPanelEvent.UNDO_STATE_CHANGED);\r
482             exp = true;\r
483         }\r
484         //try {\r
485             fTextPanel.setCommandLogSize(BIG_COMMAND_LOG_SIZE);\r
486             \r
487             if (fTextPanel.canRedo()) {\r
488                 reportError("canRedo after setCommandLogSize");\r
489             }\r
490             fListener.assertNotExpectingEvents(iterationCount, exp);\r
491         //}\r
492         //catch(Error e) {\r
493         //    logMessage("iterationCount="+iterationCount+";  expexting="+exp);\r
494         //    throw e;\r
495         //}\r
496 \r
497         MConstText insText = new StyledText("7",\r
498                                 AttributeMap.EMPTY_ATTRIBUTE_MAP);\r
499 \r
500         final int origLength = fTextPanel.getTextLength();\r
501         int start = origLength / 3;\r
502         \r
503         fListener.allowEvent(TextPanelEvent.SELECTION_RANGE_CHANGED);\r
504         fListener.allowEvent(TextPanelEvent.SELECTION_STYLES_CHANGED);\r
505 \r
506         for (int i=start; i < BIG_COMMAND_LOG_SIZE+start; i++) {\r
507             fListener.expectEvent(TextPanelEvent.UNDO_STATE_CHANGED);\r
508             fListener.expectEvent(TextPanelEvent.TEXT_CHANGED);\r
509             if (fTextPanel.getSelectionStart() != fTextPanel.getSelectionEnd()) {\r
510                 fListener.expectEvent(TextPanelEvent.SELECTION_EMPTY_CHANGED);\r
511             }\r
512             fTextPanel.insert(insText, i);\r
513             fListener.assertNotExpectingEvents();\r
514         }\r
515 \r
516         fListener.allowEvent(TextPanelEvent.SELECTION_EMPTY_CHANGED);\r
517         \r
518         for (int i=0; i < BIG_COMMAND_LOG_SIZE-1; i++) {\r
519             fListener.expectEvent(TextPanelEvent.UNDO_STATE_CHANGED);\r
520             fListener.expectEvent(TextPanelEvent.TEXT_CHANGED);\r
521             fTextPanel.undo();\r
522             fListener.assertNotExpectingEvents();\r
523         }\r
524         if (!fTextPanel.canUndo()) {\r
525             reportError("Command log is too small");\r
526         }\r
527         \r
528         fListener.allowAll();\r
529         fTextPanel.undo();\r
530         if (fTextPanel.canUndo()) {\r
531             reportError("Command log is too large");\r
532         }\r
533 \r
534         if (fTextPanel.getTextLength() != origLength * insText.length()) {\r
535             reportError("Text length was not restored");\r
536         }\r
537 \r
538         for (int i=0; i < BIG_COMMAND_LOG_SIZE; i++) {\r
539             fTextPanel.redo();\r
540         }\r
541 \r
542         if (fTextPanel.getTextLength() != origLength+BIG_COMMAND_LOG_SIZE) {\r
543             reportError("Text length was not restored after redo");\r
544         }\r
545 \r
546         if (fTextPanel.canRedo()) {\r
547             reportError("Should not be able to redo");\r
548         }\r
549 \r
550         fTextPanel.undo();\r
551 \r
552         fTextPanel.setCommandLogSize(SMALL_COMMAND_LOG_SIZE);\r
553 \r
554         if (fTextPanel.canRedo()) {\r
555             reportError("canRedo after setCommandLogSize(small)");\r
556         }\r
557 \r
558         for (int i=0; i < SMALL_COMMAND_LOG_SIZE; i++) {\r
559             if (!fTextPanel.canUndo()) {\r
560                 reportError("should be able to undo");\r
561             }\r
562             fTextPanel.undo();\r
563         }\r
564         if (fTextPanel.canUndo()) {\r
565             reportError("should not be able to undo after setCommandLogSize(small)");\r
566         }\r
567         if (!fTextPanel.canRedo()) {\r
568             reportError("why can't this redo???");\r
569         }\r
570         fTextPanel.redo();\r
571 \r
572         fTextPanel.clearCommandLog();\r
573 \r
574         if (fTextPanel.canUndo() || fTextPanel.canRedo()) {\r
575             reportError("Command log wasn't cleared");\r
576         }\r
577     }\r
578 \r
579     /**\r
580      * Test cut, copy, paste, undo, redo, clear, canUndo, canRedo.\r
581      * Text must be editable to pass this test.\r
582      */\r
583     public void _testEditMenuOperations(Clipboard clipboard) {\r
584         \r
585         if (clipboard != null) {\r
586             // test paste and undo / redo\r
587             Transferable tr = new StringSelection(STRING_CONTENT);\r
588             clipboard.setContents(tr, new ClipboardOwner() {\r
589                 public void lostOwnership(Clipboard c, Transferable t) {\r
590                 }\r
591             });\r
592             if (!fTextPanel.clipboardNotEmpty()) {\r
593                 reportError("MTextPanel doesn't recognize string content.");\r
594             }\r
595 \r
596             fTextPanel.setCaretPosition(fTextPanel.getSelectionStart());\r
597             int oldLength = fTextPanel.getTextLength();\r
598             fTextPanel.paste();\r
599             if (fTextPanel.getTextLength() != oldLength + STRING_CONTENT.length()) {\r
600                 reportError("Text length is wrong after paste.");\r
601             }\r
602 \r
603             if (!fTextPanel.canUndo()) {\r
604                 reportError("canUndo should be true");\r
605             }\r
606             fTextPanel.undo();\r
607             if (fTextPanel.getTextLength() != oldLength) {\r
608                 reportError("Length is wrong after undo");\r
609             }\r
610             if (!fTextPanel.canRedo()) {\r
611                 reportError("canRedo should be true");\r
612             }\r
613             fTextPanel.redo();\r
614             if (fTextPanel.getTextLength() != oldLength + STRING_CONTENT.length()) {\r
615                 reportError("Text length is wrong after redo.");\r
616             }\r
617         }\r
618 \r
619         int origLength = fTextPanel.getTextLength();\r
620         fTextPanel.selectAll();\r
621         fTextPanel.clear();\r
622         if (fTextPanel.getTextLength() != 0) {\r
623             reportError("Length is nonzero after clear");\r
624         }\r
625         if (!fTextPanel.canUndo()) {\r
626             reportError("canUndo should be true");\r
627         }\r
628         fTextPanel.undo();\r
629         if (fTextPanel.getTextLength() != origLength) {\r
630             reportError("Old text not restored");\r
631         }\r
632 \r
633         if (origLength > 0) {\r
634 \r
635             fTextPanel.select(0, 1);\r
636             fTextPanel.cut();\r
637             if (fTextPanel.getTextLength() != origLength-1) {\r
638                 reportError("Length wrong after cut");\r
639             }\r
640             fTextPanel.paste();\r
641             if (fTextPanel.getTextLength() != origLength) {\r
642                 reportError("Length wrong after paste");\r
643             }\r
644             fTextPanel.select(0, origLength);\r
645             fTextPanel.copy();\r
646             fTextPanel.setCaretPosition(0);\r
647             fTextPanel.paste();\r
648             if (fTextPanel.getTextLength() != 2*origLength) {\r
649                 reportError("Length wrong after paste");\r
650             }\r
651             fTextPanel.undo();\r
652             if (fTextPanel.getTextLength() != origLength) {\r
653                 reportError("Length wrong after undo");\r
654             }\r
655         }\r
656     }\r
657 \r
658     private void setAndTestModFlag(final int depth,\r
659                                    boolean modified) {\r
660 \r
661         fTextPanel.setModified(modified);\r
662         for (int i=0; i < depth; i++) {\r
663             if (!fTextPanel.canUndo()) {\r
664                 reportError("Panel cannot undo at valid depth.  Depth=" + i);\r
665             }\r
666             fTextPanel.undo();\r
667             fTextPanel.setModified(modified);\r
668         }\r
669 \r
670         // check that all mod flags are false:\r
671         if (fTextPanel.isModified() != modified) {\r
672             reportError("isModified is not correct");\r
673         }\r
674 \r
675         for (int i=0; i < depth; i++) {\r
676             fTextPanel.redo();\r
677             if (fTextPanel.isModified() != modified) {\r
678                 reportError("isModified is not correct");\r
679             }\r
680         }\r
681     }\r
682 \r
683     /**\r
684      * Make <code>depth</code> modifications to the text in textfTextPanel.\r
685      * Set the modified flag on each operation, and then retrieve its\r
686      * value.  Finally, undo the modifications.\r
687      */\r
688     public void _testModFlag(final int depth) {\r
689 \r
690         final int oldLength = fTextPanel.getTextLength();\r
691 \r
692         for (int i=0; i < depth; i++) {\r
693             fTextPanel.insert(MOD_TEXT, 0);\r
694         }\r
695 \r
696         setAndTestModFlag(depth, false);\r
697         setAndTestModFlag(depth, true);\r
698 \r
699         for (int i=0; i < depth; i++) {\r
700             fTextPanel.undo();\r
701         }\r
702 \r
703         if (fTextPanel.getTextLength() != oldLength) {\r
704             reportError("Undo did not restore old text.");\r
705         }\r
706     }\r
707 \r
708     void applyCharacterStyle() {\r
709 \r
710         StyleModifier stMod = charMods[randInt(charMods.length)];\r
711         fListener.refuseAll();\r
712         fListener.expectEvent(TextPanelEvent.SELECTION_STYLES_CHANGED);\r
713         if (fTextPanel.getSelectionStart() != fTextPanel.getSelectionEnd()) {\r
714             fListener.expectEvent(TextPanelEvent.TEXT_CHANGED);\r
715             fListener.allowEvent(TextPanelEvent.SELECTION_RANGE_CHANGED);\r
716         }\r
717         fListener.allowEvent(TextPanelEvent.UNDO_STATE_CHANGED);\r
718         fTextPanel.modifyCharacterStyleOnSelection(stMod);\r
719         fListener.assertNotExpectingEvents();\r
720         fListener.allowAll();\r
721     }\r
722 \r
723 \r
724     void applyParagraphStyle() {\r
725 \r
726         fListener.refuseAll();\r
727         fListener.expectEvent(TextPanelEvent.SELECTION_STYLES_CHANGED);\r
728         fListener.expectEvent(TextPanelEvent.TEXT_CHANGED);\r
729         fListener.allowEvent(TextPanelEvent.UNDO_STATE_CHANGED);\r
730         fListener.allowEvent(TextPanelEvent.SELECTION_RANGE_CHANGED);\r
731         StyleModifier stMod = paraMods[randInt(paraMods.length)];\r
732         fTextPanel.modifyParagraphStyleOnSelection(stMod);\r
733         fListener.assertNotExpectingEvents();\r
734         fListener.allowAll();\r
735     }\r
736 \r
737     void applyKeyRemap() {\r
738 \r
739         fListener.refuseAll();\r
740         fListener.expectEvent(TextPanelEvent.KEYREMAP_CHANGED);\r
741         int op = randInt(5);\r
742         switch (op) {\r
743 \r
744             case 0:\r
745                 fTextPanel.setKeyRemap(KeyRemap.getIdentityRemap());\r
746                 break;\r
747 \r
748             case 1:\r
749                 fTextPanel.setKeyRemap(KeyRemap.getArabicTransliteration());\r
750                 break;\r
751 \r
752             case 2:\r
753                 fTextPanel.setKeyRemap(KeyRemap.getHebrewTransliteration());\r
754                 break;\r
755 \r
756             case 3:\r
757                 fTextPanel.setKeyRemap(KeyRemap.getIsraelNikud());\r
758                 break;\r
759             \r
760             case 4:\r
761                 //fTextPanel.setKeyRemap(KeyRemap.getThaiKetmanee());\r
762                 fTextPanel.setKeyRemap(KeyRemap.getIsraelNikud());\r
763                 break;\r
764             \r
765             default:\r
766                 reportError("Invalid operation!");\r
767         }\r
768         fListener.assertNotExpectingEvents();\r
769         fListener.allowAll();\r
770     }\r
771 \r
772     void resizeFrame(Frame frame) {\r
773 \r
774         fListener.refuseAll();\r
775         fListener.allowEvent(TextPanelEvent.FORMAT_WIDTH_CHANGED);\r
776         int wd = randInt(50, 1000);\r
777         int ht = randInt(20, 800);\r
778 \r
779         frame.setSize(wd, ht);\r
780         fListener.allowAll();\r
781     }\r
782 \r
783     void selectText() {\r
784 \r
785         int selStart = randInt(-10, fTextPanel.getTextLength());\r
786         int selLimit = randInt(0, fTextPanel.getTextLength() + 10);\r
787         _testSelection(SELECT, selStart, selLimit);\r
788     }\r
789 \r
790     void undoRedo() {\r
791 \r
792         final int opCount = randInt(-10, 15);\r
793 \r
794         for (int i=opCount; i <= 0; i++) {\r
795             fTextPanel.redo();\r
796         }\r
797         for (int i=0; i < opCount; i++) {\r
798             fTextPanel.undo();\r
799         }\r
800     }\r
801     \r
802     void typeKeys() {\r
803 \r
804         final int keyCount = randInt(1, 100);\r
805         TextPanel textPanel = (TextPanel) fTextPanel;\r
806         \r
807         KeyEventForwarder forwarder = new KeyEventForwarder(textPanel);\r
808         \r
809         fListener.refuseAll();\r
810         fListener.allowEvent(TextPanelEvent.UNDO_STATE_CHANGED);\r
811         \r
812         if (fTextPanel.getSelectionStart() != fTextPanel.getSelectionEnd()) {\r
813             fListener.expectEvent(TextPanelEvent.SELECTION_EMPTY_CHANGED);\r
814         }\r
815         \r
816         for (int i=0; i < keyCount; i++) {\r
817             char typedChar = TYPED_CHARS[randInt(TYPED_CHARS.length)];\r
818             KeyEvent event = new KeyEvent(textPanel,\r
819                                           KeyEvent.KEY_TYPED,\r
820                                           0,\r
821                                           0,\r
822                                           KeyEvent.VK_UNDEFINED,\r
823                                           typedChar);\r
824             if (typedChar == 8 || typedChar == 0x7f) {\r
825                 fListener.allowEvent(TextPanelEvent.TEXT_CHANGED);\r
826                 fListener.allowEvent(TextPanelEvent.SELECTION_RANGE_CHANGED);\r
827             }\r
828             else {\r
829                 fListener.expectEvent(TextPanelEvent.TEXT_CHANGED);\r
830                 fListener.expectEvent(TextPanelEvent.SELECTION_RANGE_CHANGED);\r
831             }\r
832             forwarder.handleKeyEvent(event);\r
833             //try {\r
834                 fListener.assertNotExpectingEvents(i, false);\r
835             //}\r
836             //catch(Error e) {\r
837             //    logMessage("i="+i+"; typedChar="+Integer.toHexString(typedChar));\r
838             //    throw e;\r
839             //}\r
840         }\r
841         fListener.allowAll();\r
842     }\r
843 }\r