001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Evgeniya G. Maenkova
019: * @version $Revision$
020: */package javax.swing.undo;
021:
022: import javax.swing.UIManager;
023: import javax.swing.event.UndoableEditEvent;
024:
025: public class UndoManagerTest extends CompoundEditTest {
026: protected UndoManager um;
027:
028: @Override
029: protected void setUp() throws Exception {
030: super .setUp();
031: um = new UndoManager();
032: ce = um;
033: obj = um;
034: }
035:
036: @Override
037: public void testToString() {
038: assertNotNull(um.toString());
039: }
040:
041: @Override
042: public void testCanUndo() {
043: assertFalse(um.canUndo());
044: TestUndoableEdit edit1 = new TestUndoableEdit(
045: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
046: um.addEdit(edit1);
047: //canUndo must call isSignificant
048: assertFalse(um.canUndo());
049: edit1.flag |= TestUndoableEdit.CAN_UNDO_FALSE;
050: TestUndoableEdit edit2 = new TestUndoableEdit(
051: TestUndoableEdit.IS_SIGNIFICANT_TRUE);
052: um.addEdit(edit2);
053: //if edit is significant then canUndo must be called
054: assertEquals(um.canUndo(), edit2.canUndo());
055: edit2.flag |= TestUndoableEdit.CAN_UNDO_FALSE;
056: assertEquals(um.canUndo(), edit2.canUndo());
057: edit2.flag = TestUndoableEdit.IS_SIGNIFICANT_TRUE;
058: //move index to 1
059: um.undo();
060: //canUndo must return false because
061: //there is no any significant edit before indexOfNextAdd
062: assertFalse(um.canUndo());
063: //back index to 2
064: um.redo();
065: TestUndoableEdit edit3 = new TestUndoableEdit(
066: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
067: um.addEdit(edit3);
068: TestUndoableEdit edit4 = new TestUndoableEdit(
069: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
070: um.addEdit(edit4);
071: //isSignificant must be call from the end to start
072: // we must stop on significant edit and call canUndo
073: edit2.flag = TestUndoableEdit.IS_SIGNIFICANT_TRUE;
074: assertEquals(um.canUndo(), edit2.canUndo());
075: edit2.flag |= TestUndoableEdit.CAN_UNDO_FALSE;
076: assertEquals(um.canUndo(), edit2.canUndo());
077: //first significant's canUndo returns false
078: //second's one returns true
079: edit3.flag = TestUndoableEdit.IS_SIGNIFICANT_TRUE
080: | TestUndoableEdit.CAN_UNDO_FALSE;
081: edit2.flag = TestUndoableEdit.IS_SIGNIFICANT_TRUE;
082: // must look only on last significant
083: assertEquals(um.canUndo(), edit3.canUndo());
084: //if not inProgress
085: //set inProgress to false
086: um.end();
087: assertFalse(um.isInProgress());
088: //now um must call to super.canUndo
089: // must be true if alive && hasBeenDone
090: assertTrue(um.canUndo());
091: //die sets alive to false
092: um.die();
093: assertFalse(um.canUndo());
094: }
095:
096: @Override
097: public void testCanRedo() {
098: //empty must return false
099: assertFalse(um.canRedo());
100: TestUndoableEdit edit1 = new TestUndoableEdit(
101: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
102: um.addEdit(edit1);
103: //canRedo must call isSignificant
104: assertFalse(um.canRedo());
105: edit1.flag |= TestUndoableEdit.CAN_REDO_FALSE;
106: TestUndoableEdit edit2 = new TestUndoableEdit(
107: TestUndoableEdit.IS_SIGNIFICANT_TRUE);
108: um.addEdit(edit2);
109: //if edit is significant then canUndo must be called
110: assertFalse(edit2.canRedo());
111: assertEquals(um.canRedo(), edit2.canRedo());
112: TestUndoableEdit edit3 = new TestUndoableEdit(
113: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
114: um.addEdit(edit3);
115: // false because there is no significant at indexOfNextAdd or after it
116: assertFalse(um.canRedo());
117: //move indexOfNextAdd to 1 and call undo for edit2 & edit 3
118: um.undo();
119: //canRedo must be called for significant edit at indexOfNextAdd or
120: // after
121: assertEquals(um.canRedo(), edit2.canRedo());
122: edit2.flag |= TestUndoableEdit.CAN_REDO_FALSE;
123: assertEquals(um.canRedo(), edit2.canRedo());
124: edit2.flag = TestUndoableEdit.IS_SIGNIFICANT_FALSE;
125: // canRedo must return false because there is no any significant edit
126: assertFalse(um.canRedo());
127: edit3.flag = TestUndoableEdit.IS_SIGNIFICANT_TRUE;
128: assertEquals(um.canRedo(), edit3.canRedo());
129: edit3.flag |= TestUndoableEdit.CAN_REDO_FALSE;
130: assertEquals(um.canRedo(), edit3.canRedo());
131: // set inProgress to false
132: um.end();
133: assertFalse(um.isInProgress());
134: //now um must call to super.canRedo
135: // must be true if alive && !hasBeenDone
136: assertFalse(um.canRedo());
137: um.undo();
138: assertTrue(um.canRedo());
139: //die sets alive to false
140: um.die();
141: assertFalse(um.canRedo());
142: }
143:
144: @Override
145: public void testUndo() {
146: TestUndoableEdit.counter = 0;
147: um.addEdit(new TestUndoableEdit(
148: TestUndoableEdit.IS_SIGNIFICANT_TRUE));
149: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO));
150: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO
151: | TestUndoableEdit.IS_SIGNIFICANT_FALSE));
152: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO
153: | TestUndoableEdit.IS_SIGNIFICANT_FALSE));
154: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO
155: | TestUndoableEdit.IS_SIGNIFICANT_FALSE));
156: assertEquals(5, um.indexOfNextAdd);
157: um.undo();
158: //indexOfNextAdd must be on last significant edit (second edit)
159: assertEquals(1, um.indexOfNextAdd);
160: um.discardAllEdits();
161: TestUndoableEdit.counter = 0;
162: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO));
163: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO));
164: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO));
165: assertEquals(3, um.indexOfNextAdd);
166: assertEquals(3, um.edits.size());
167: //must be called only for last edit
168: um.undo();
169: assertEquals(2, TestUndoableEdit.counter);
170: //index must be on last edit
171: assertEquals(2, um.indexOfNextAdd);
172: //set inProgress to false
173: um.end();
174: //and also remove last edit because it beyond indexOfNextAdd
175: TestUndoableEdit.counter = 2;
176: //undo must be called for remain 2 edits
177: um.undo();
178: assertEquals(0, TestUndoableEdit.counter);
179: um = new UndoManager();
180: boolean bWasException = false;
181: try {
182: um.undo();
183: } catch (CannotUndoException e) {
184: bWasException = true;
185: }
186: assertTrue("CannotUndoException was expected", bWasException);
187: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO
188: | TestUndoableEdit.IS_SIGNIFICANT_FALSE));
189: bWasException = false;
190: try {
191: um.undo();
192: } catch (CannotUndoException e) {
193: bWasException = true;
194: }
195: assertTrue("CannotUndoException was expected", bWasException);
196: um = new UndoManager();
197: TestUndoableEdit.counter = 0;
198: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO));
199: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO));
200: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO
201: | TestUndoableEdit.IS_SIGNIFICANT_FALSE));
202: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO));
203: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO
204: | TestUndoableEdit.IS_SIGNIFICANT_FALSE));
205: assertEquals(5, um.indexOfNextAdd);
206: um.undo();
207: assertEquals(3, um.indexOfNextAdd);
208: um.undo();
209: um.undo();
210: }
211:
212: @Override
213: public void testRedo() {
214: TestUndoableEdit.counter = 0;
215: TestUndoableEdit edit1 = new TestUndoableEdit(
216: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
217: um.addEdit(edit1);
218: TestUndoableEdit edit2 = new TestUndoableEdit(
219: TestUndoableEdit.IS_SIGNIFICANT_TRUE);
220: um.addEdit(edit2);
221: TestUndoableEdit edit3 = new TestUndoableEdit(
222: TestUndoableEdit.IS_SIGNIFICANT_TRUE
223: | TestUndoableEdit.UNDO);
224: um.addEdit(edit3);
225: TestUndoableEdit edit4 = new TestUndoableEdit(
226: TestUndoableEdit.IS_SIGNIFICANT_FALSE
227: | TestUndoableEdit.UNDO);
228: um.addEdit(edit4);
229: TestUndoableEdit edit5 = new TestUndoableEdit(
230: TestUndoableEdit.IS_SIGNIFICANT_FALSE
231: | TestUndoableEdit.UNDO);
232: um.addEdit(edit5);
233: //first we call undo
234: um.undo();
235: //index must be on 2
236: // and undo was called for edit3, then for edit4 and last for edit5
237: assertEquals(2, um.indexOfNextAdd);
238: assertTrue(um.canRedo());
239: edit3.id = 0;
240: edit3.flag = TestUndoableEdit.REDO
241: | TestUndoableEdit.IS_SIGNIFICANT_FALSE;
242: edit2.id = -2;
243: edit2.flag = TestUndoableEdit.REDO
244: | TestUndoableEdit.IS_SIGNIFICANT_FALSE;
245: edit1.id = -1;
246: edit1.flag |= TestUndoableEdit.REDO;
247: edit4.id = 1;
248: edit4.flag = TestUndoableEdit.REDO
249: | TestUndoableEdit.IS_SIGNIFICANT_FALSE;
250: edit5.id = 2;
251: edit5.flag = TestUndoableEdit.REDO
252: | TestUndoableEdit.IS_SIGNIFICANT_TRUE;
253: TestUndoableEdit.counter = 0;
254: assertTrue(um.canRedo());
255: //redo must be called first for edit3, then for edit3 & edit2
256: assertEquals(2, um.indexOfNextAdd);
257: // 1) edit3.isSignificant? false
258: // 2) edit4.isSignificant? false
259: // 3) edit5.isSignificant? true
260: // 4) edit3.redo
261: // 5) edit4.redo
262: // 6) edit5.redo
263: // find significant starting from indexOfNextAdd -> END
264: // call redo starting from indexOfNextAdd -> significant
265: um.redo();
266: um.discardAllEdits();
267: boolean bWasException = false;
268: try {
269: um.redo();
270: } catch (CannotRedoException e) {
271: bWasException = true;
272: }
273: assertTrue("CannotRedoException was expected", bWasException);
274: //set inProgress to false
275: um.end();
276: // set hasBeenDone to false
277: um.undo();
278: // call must lead to super.redo
279: // exception must not be thrown
280: um.redo();
281: bWasException = false;
282: try {
283: um.redo();
284: } catch (CannotRedoException e) {
285: bWasException = true;
286: }
287: assertTrue("CannotRedoException was expected", bWasException);
288: }
289:
290: @Override
291: public void testEnd() {
292: um.addEdit(new TestUndoableEdit(TestUndoableEdit.DIE));
293: um.addEdit(new TestUndoableEdit(TestUndoableEdit.DIE));
294: um.addEdit(new TestUndoableEdit(TestUndoableEdit.DIE));
295: um.addEdit(new TestUndoableEdit(TestUndoableEdit.DIE));
296: um.undo();
297: um.undo();
298: um.undo();
299: // we moved indexOfNextAdd from 4 to 1
300: assertEquals(1, um.indexOfNextAdd);
301: um.end();
302: // must be called:
303: // 1) edit3.die
304: // 2) edit2.die
305: // 3) edit1.die
306: assertFalse(um.isInProgress());
307: assertEquals(1, um.edits.size());
308: }
309:
310: public void testGetLimit() {
311: assertEquals(100, um.getLimit());
312: }
313:
314: public void testDiscardAllEdits() {
315: // call for empty manager
316: // nothing should happen
317: um.discardAllEdits();
318: //add several edits with DISCARD flag
319: final int editCount = 10;
320: TestUndoableEdit[] edits = new TestUndoableEdit[editCount];
321: for (int i = 0; i < editCount; i++) {
322: edits[i] = new TestUndoableEdit(TestUndoableEdit.DISCARD);
323: um.addEdit(edits[i]);
324: }
325: um.setLimit(200);
326: um.discardAllEdits();
327: //check that every edit was discard
328: for (int i = 0; i < editCount; i++) {
329: assertTrue(edits[i].isDieCalled());
330: }
331: assertEquals(0, um.edits.size());
332: assertEquals(0, um.indexOfNextAdd);
333: assertEquals(200, um.getLimit());
334: um = new UndoManager();
335: um.end();
336: um.undo();
337: assertFalse(um.isInProgress());
338: assertFalse(hasBeenDone(um));
339: um.discardAllEdits();
340: assertFalse(um.isInProgress());
341: assertFalse(hasBeenDone(um));
342: }
343:
344: public void testTrimForLimit() {
345: //add a lot of edits with DISCARD flag
346: final int editCount = 200;
347: TestUndoableEdit[] edits = new TestUndoableEdit[editCount];
348: for (int i = 0; i < editCount; i++) {
349: edits[i] = new TestUndoableEdit(TestUndoableEdit.DISCARD);
350: // it allows to move indexOfNextAdd to limit and stay it there
351: if (i < um.getLimit()) {
352: um.addEdit(edits[i]);
353: } else {
354: um.edits.add(edits[i]);
355: }
356: //so indexOfNextAdd == limit
357: }
358: assertEquals(100, um.indexOfNextAdd);
359: um.trimForLimit();
360: assertEquals(um.edits.size(), um.getLimit());
361: int limit = um.getLimit();
362: // indexOfNextAdd must be a center
363: for (int i = 0; i < editCount; i++) {
364: if (i < limit / 2 || i > limit * 3 / 2 - 1) {
365: assertTrue(edits[i].isDieCalled());
366: } else {
367: assertFalse(edits[i].isDieCalled());
368: }
369: }
370: assertEquals(limit, um.edits.size());
371: }
372:
373: public void testUndoOrRedo() {
374: //must throw exception if edits is empty
375: boolean wasException = false;
376: try {
377: um.undoOrRedo();
378: } catch (CannotUndoException e) {
379: wasException = true;
380: }
381: assertTrue("CannotUndoException was expected", wasException);
382: //it makes sense to use undoOrRedo only when limit is equal to 1
383: um.setLimit(1);
384: TestUndoableEdit.counter = 0;
385: um.addEdit(new TestUndoableEdit(TestUndoableEdit.UNDO));
386: assertEquals(1, um.indexOfNextAdd);
387: //first it should call to undo
388: um.undoOrRedo();
389: assertEquals(0, TestUndoableEdit.counter);
390: assertEquals(0, um.indexOfNextAdd);
391: um.edits.set(0, new TestUndoableEdit(TestUndoableEdit.REDO));
392: //then it should call to redo
393: TestUndoableEdit.counter = 0;
394: um.undoOrRedo();
395: assertEquals(1, TestUndoableEdit.counter);
396: assertEquals(1, um.indexOfNextAdd);
397: TestUndoableEdit.counter = 0;
398: um.edits.set(0, new TestUndoableEdit(TestUndoableEdit.UNDO));
399: um.undoOrRedo();
400: assertEquals(0, TestUndoableEdit.counter);
401: assertEquals(0, um.indexOfNextAdd);
402: um.end();
403: // nothing must be call
404: um.undoOrRedo();
405: }
406:
407: public void testCanUndoOrRedo() {
408: //must be false if edits is empty
409: assertFalse(um.canUndoOrRedo());
410: //it makes sense to use canUndoOrRedo only when limit is equal to 1
411: um.setLimit(1);
412: TestUndoableEdit edit = new TestUndoableEdit(
413: TestUndoableEdit.UNDO);
414: um.addEdit(edit);
415: assertTrue(um.canUndoOrRedo());
416: um.discardAllEdits();
417: assertFalse(um.canUndoOrRedo());
418: um = new UndoManager();
419: um.addEdit(edit);
420: assertTrue(um.canUndoOrRedo());
421: um.end();
422: // it doesn't depend from inProgress
423: assertTrue(um.canUndoOrRedo());
424: }
425:
426: public void testSetLimit() {
427: final int editCount = 100;
428: TestUndoableEdit[] edits = new TestUndoableEdit[editCount];
429: TestUndoableEdit.counter = 0;
430: final int newLimit = 50;
431: for (int i = 0; i < editCount; i++) {
432: if (i < newLimit) {
433: edits[i] = new TestUndoableEdit(
434: TestUndoableEdit.DISCARD);
435: } else {
436: edits[i] = new TestUndoableEdit(TestUndoableEdit.DIE);
437: }
438: um.edits.add(edits[i]);
439: }
440: um.setLimit(newLimit);
441: assertEquals(newLimit, um.getLimit());
442: assertEquals(newLimit, um.edits.size());
443: for (int i = 0; i < editCount; i++) {
444: if (i < newLimit) {
445: assertFalse(edits[i].isDieCalled());
446: } else {
447: assertTrue(edits[i].isDieCalled());
448: }
449: }
450: //Regression test for H2538
451: um.setLimit(-5);
452: }
453:
454: public void testTrimEdits() {
455: //add a lot of edits with DISCARD flag
456: final int editCount = 200;
457: TestUndoableEdit[] edits = new TestUndoableEdit[editCount];
458: for (int i = 0; i < editCount; i++) {
459: edits[i] = new TestUndoableEdit(TestUndoableEdit.DISCARD);
460: um.edits.add(edits[i]);
461: }
462: final int from = 25, to = 75;
463: um.trimEdits(from, to);
464: for (int i = 0; i < editCount; i++) {
465: if (i < from || i > to) {
466: assertFalse(edits[i].isDieCalled());
467: } else {
468: assertTrue(edits[i].isDieCalled());
469: }
470: }
471: }
472:
473: /*
474: * Class under test for java.lang.String getRedoPresentationName()
475: */
476: @Override
477: public void testGetRedoPresentationName() {
478: assertEquals(UIManager
479: .getString("AbstractUndoableEdit.redoText"), um
480: .getRedoPresentationName());
481: TestUndoableEdit edit1 = new TestUndoableEdit(
482: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
483: um.addEdit(edit1);
484: TestUndoableEdit edit2 = new TestUndoableEdit(
485: TestUndoableEdit.REDO_NAME
486: | TestUndoableEdit.IS_SIGNIFICANT_TRUE);
487: um.addEdit(edit2);
488: um.addEdit(new TestUndoableEdit(
489: TestUndoableEdit.IS_SIGNIFICANT_FALSE));
490: um.undo();
491: // returns getRedoPresentationName of significant edit
492: assertEquals(edit2.getRedoPresentationName(), um
493: .getRedoPresentationName());
494: edit2.flag = TestUndoableEdit.REDO_NAME
495: | TestUndoableEdit.IS_SIGNIFICANT_FALSE;
496: assertEquals(UIManager
497: .getString("AbstractUndoableEdit.redoText"), um
498: .getRedoPresentationName());
499: um.end();
500: // not inProgress
501: assertEquals(1, um.edits.size());
502: assertFalse(um.isInProgress());
503: edit1.flag |= TestUndoableEdit.REDO_NAME;
504: assertEquals(edit1, um.edits.get(0));
505: assertEquals(edit1.getRedoPresentationName(), um
506: .getRedoPresentationName());
507: }
508:
509: public void testGetUndoOrRedoPresentationName() {
510: TestUndoableEdit.counter = 0;
511: um.setLimit(1);
512: TestUndoableEdit edit = new TestUndoableEdit(
513: TestUndoableEdit.UNDO_NAME);
514: um.addEdit(edit);
515: //before undo function must call to edit.getUndoPresentationName
516: assertEquals(edit.getUndoPresentationName(), um
517: .getUndoOrRedoPresentationName());
518: um.undoOrRedo();
519: edit.flag = TestUndoableEdit.REDO_NAME;
520: //before undo function must call to edit.getUndoPresentationName
521: assertEquals(edit.getRedoPresentationName(), um
522: .getUndoOrRedoPresentationName());
523: //back to undo name
524: um.undoOrRedo();
525: edit.flag = TestUndoableEdit.UNDO_NAME;
526: assertEquals(edit.getUndoPresentationName(), um
527: .getUndoOrRedoPresentationName());
528: }
529:
530: /*
531: * Class under test for java.lang.String getUndoPresentationName()
532: */
533: @Override
534: public void testGetUndoPresentationName() {
535: assertEquals(UIManager
536: .getString("AbstractUndoableEdit.undoText"), um
537: .getUndoPresentationName());
538: um.addEdit(new TestUndoableEdit(
539: TestUndoableEdit.IS_SIGNIFICANT_FALSE));
540: TestUndoableEdit edit2 = new TestUndoableEdit(
541: TestUndoableEdit.UNDO_NAME
542: | TestUndoableEdit.IS_SIGNIFICANT_TRUE);
543: um.addEdit(edit2);
544: TestUndoableEdit edit3 = new TestUndoableEdit(
545: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
546: um.addEdit(edit3);
547: // returns getUndoPresentationName of significant edit
548: assertEquals(edit2.getUndoPresentationName(), um
549: .getUndoPresentationName());
550: edit2.flag = TestUndoableEdit.UNDO_NAME
551: | TestUndoableEdit.IS_SIGNIFICANT_FALSE;
552: assertEquals(UIManager
553: .getString("AbstractUndoableEdit.undoText"), um
554: .getUndoPresentationName());
555: um.end();
556: // not inProgress
557: assertEquals(3, um.edits.size());
558: assertFalse(um.isInProgress());
559: // last edit is edit3
560: edit3.flag |= TestUndoableEdit.UNDO_NAME;
561: assertEquals(edit3, um.lastEdit());
562: assertEquals(edit3.getUndoPresentationName(), um
563: .getUndoPresentationName());
564: }
565:
566: public void testUndoableEditHappened() {
567: UndoableEdit edit = new TestUndoableEdit();
568: UndoableEditEvent event = new UndoableEditEvent(this , edit);
569: um.undoableEditHappened(event);
570: assertEquals(1, um.edits.size());
571: assertEquals(edit, um.edits.get(0));
572: }
573:
574: public void testEditToBeRedone() {
575: //add a lot of edits with IS_SIGNIFICANT_FALSE flag
576: //and a first with IS_SIGNIFICANT_TRUE flag
577: final int editCount = 100;
578: TestUndoableEdit[] edits = new TestUndoableEdit[editCount];
579: edits[0] = new TestUndoableEdit(
580: TestUndoableEdit.IS_SIGNIFICANT_TRUE);
581: um.addEdit(edits[0]);
582: for (int i = 1; i < editCount; i++) {
583: edits[i] = new TestUndoableEdit(
584: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
585: um.addEdit(edits[i]);
586: }
587: um.undo();
588: assertEquals(0, um.indexOfNextAdd);
589: assertEquals(edits[0], um.editToBeRedone());
590: //when undo was called only edits[0] was undoable
591: //so indexOfNextAdd is located in 0 and
592: //the result must be equal to edits[0]
593: edits[50].flag = TestUndoableEdit.IS_SIGNIFICANT_TRUE;
594: assertEquals(edits[0], um.editToBeRedone());
595: //it must be null if there are no any significant edit
596: edits[0].flag = TestUndoableEdit.IS_SIGNIFICANT_FALSE;
597: edits[50].flag = TestUndoableEdit.IS_SIGNIFICANT_FALSE;
598: assertNull(um.editToBeRedone());
599: um = new UndoManager();
600: edits = new TestUndoableEdit[editCount];
601: edits[0] = new TestUndoableEdit(
602: TestUndoableEdit.IS_SIGNIFICANT_TRUE);
603: um.addEdit(edits[0]);
604: for (int i = 1; i < editCount; i++) {
605: edits[i] = new TestUndoableEdit(
606: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
607: um.addEdit(edits[i]);
608: }
609: edits[50].flag = TestUndoableEdit.IS_SIGNIFICANT_TRUE;
610: um.undo();
611: assertEquals(edits[50], um.editToBeRedone());
612: um.undo();
613: assertEquals(edits[0], um.editToBeRedone());
614: //it must be null if there are no any significant edit
615: edits[0].flag = TestUndoableEdit.IS_SIGNIFICANT_FALSE;
616: edits[50].flag = TestUndoableEdit.IS_SIGNIFICANT_FALSE;
617: assertNull(um.editToBeRedone());
618: }
619:
620: public void testEditToBeUndone() {
621: //add a lot of edits with IS_SIGNIFICANT_FALSE flag
622: //and a first with IS_SIGNIFICANT_TRUE flag
623: final int editCount = 100;
624: TestUndoableEdit[] edits = new TestUndoableEdit[editCount];
625: edits[0] = new TestUndoableEdit(
626: TestUndoableEdit.IS_SIGNIFICANT_TRUE);
627: um.addEdit(edits[0]);
628: for (int i = 1; i < editCount; i++) {
629: edits[i] = new TestUndoableEdit(
630: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
631: um.addEdit(edits[i]);
632: }
633: assertEquals(edits[0], um.editToBeUndone());
634: //returned edit should be first in reverse of the order they were added
635: edits[50].flag = TestUndoableEdit.IS_SIGNIFICANT_TRUE;
636: assertEquals(edits[50], um.editToBeUndone());
637: //returned edit must be null if there are no any significant edit
638: edits[0].flag = TestUndoableEdit.IS_SIGNIFICANT_FALSE;
639: edits[50].flag = TestUndoableEdit.IS_SIGNIFICANT_FALSE;
640: assertNull(um.editToBeUndone());
641: edits[99].flag = TestUndoableEdit.IS_SIGNIFICANT_TRUE;
642: assertEquals(edits[99], um.editToBeUndone());
643: }
644:
645: public void testRedoTo() {
646: final int editCount = 100;
647: TestUndoableEdit[] edits = new TestUndoableEdit[editCount];
648: TestUndoableEdit.counter = 0;
649: final int start = 20, end = 50;
650: for (int i = 0; i < editCount; i++) {
651: if (i >= start && i < end) {
652: edits[i] = new TestUndoableEdit(TestUndoableEdit.UNDO);
653: } else {
654: edits[i] = new TestUndoableEdit(
655: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
656: }
657: um.addEdit(edits[i]);
658: }
659: final int limit = 30;
660: assertEquals(editCount, um.indexOfNextAdd);
661: um.undoTo(edits[limit]);
662: assertEquals(limit, um.indexOfNextAdd);
663: //undo must be called only from END -> START
664: //and must stop on TO
665: //method undo must not be called for TO - START edits
666: //indexOfNextAdd must be replaced to edits[TO]
667: assertEquals(limit - start, TestUndoableEdit.counter);
668: TestUndoableEdit.counter = 0;
669: final int countRedo = 40;
670: for (int i = limit; i < end; i++) {
671: edits[i] = new TestUndoableEdit(TestUndoableEdit.REDO);
672: um.edits.set(i, edits[i]);
673: }
674: TestUndoableEdit.counter = 0;
675: um.redoTo(edits[countRedo]);
676: //undo must be called only from TO -> END
677: //and must stop on TO_REDO
678: //method undo must not be called for TO_REDO - TO + 1 edits
679: //indexOfNextAdd must be replaced to edits[TO_REDO]
680: assertEquals(countRedo - limit + 1, TestUndoableEdit.counter);
681: assertEquals(countRedo + 1, um.indexOfNextAdd);
682: um = new UndoManager();
683: UndoableEdit ed = new AbstractUndoableEdit() {
684: private static final long serialVersionUID = 1L;
685:
686: @Override
687: public boolean canRedo() {
688: return false;
689: }
690: };
691: um.addEdit(ed);
692: // to move indexOfNextAdd from last edit to ed
693: um.undoTo(ed);
694: boolean bWasException = false;
695: try {
696: um.redoTo(ed);
697: } catch (CannotRedoException e) {
698: bWasException = true;
699: }
700: assertTrue("CannotRedoException was expected", bWasException);
701: }
702:
703: public void testUndoTo_AIOOB() { // Regression test for HARMONY-2612
704: UndoManager um = new UndoManager();
705: um.addEdit(new AbstractUndoableEdit());
706: try {
707: um.undoTo(null);
708: fail("CannotUndoException should have been thrown");
709: } catch (CannotUndoException e) {
710: // Expected
711: }
712: }
713:
714: public void testRedoTo_AIOOB() { // Regression test for HARMONY-2612
715: UndoManager um = new UndoManager();
716: um.addEdit(new AbstractUndoableEdit());
717: try {
718: um.redoTo(null);
719: fail("CannotRedoException should have been thrown");
720: } catch (CannotRedoException e) {
721: // Expected
722: }
723: }
724:
725: public void testUndoTo() {
726: final int editCount = 100;
727: TestUndoableEdit[] edits = new TestUndoableEdit[editCount];
728: TestUndoableEdit.counter = 0;
729: for (int i = 0; i < editCount; i++) {
730: if (i < 50) {
731: edits[i] = new TestUndoableEdit(TestUndoableEdit.UNDO);
732: } else {
733: edits[i] = new TestUndoableEdit(
734: TestUndoableEdit.IS_SIGNIFICANT_FALSE);
735: }
736: um.addEdit(edits[i]);
737: }
738: assertEquals(editCount, um.indexOfNextAdd);
739: um.undoTo(edits[40]);
740: assertEquals(40, TestUndoableEdit.counter);
741: assertEquals(40, um.indexOfNextAdd);
742: um = new UndoManager();
743: UndoableEdit ed = new AbstractUndoableEdit() {
744: private static final long serialVersionUID = 1L;
745:
746: @Override
747: public boolean canUndo() {
748: return false;
749: }
750: };
751: um.addEdit(ed);
752: boolean bWasException = false;
753: try {
754: um.undoTo(ed);
755: } catch (CannotUndoException e) {
756: bWasException = true;
757: }
758: assertTrue("CannotUndoException was expected", bWasException);
759: }
760:
761: /*
762: * Class under test for boolean addEdit(javax.swing.undo.UndoableEdit)
763: */
764: public void testAddEditUndoableEdit() {
765: // if end was called then UndoManager acts as CompoundEdit
766: um.end();
767: // returns false and doesn't add anything
768: assertFalse(um.addEdit(new TestUndoableEdit(
769: TestUndoableEdit.DIE)));
770: assertEquals(0, um.edits.size());
771: um = new UndoManager();
772: TestUndoableEdit.counter = 0;
773: TestUndoableEdit edit1 = new TestUndoableEdit();
774: assertTrue(um.addEdit(edit1));
775: assertEquals(1, um.indexOfNextAdd);
776: TestUndoableEdit edit2 = new TestUndoableEdit(
777: TestUndoableEdit.DIE);
778: assertTrue(um.addEdit(edit2));
779: assertEquals(2, um.indexOfNextAdd);
780: TestUndoableEdit edit3 = new TestUndoableEdit(
781: TestUndoableEdit.DIE);
782: assertTrue(um.addEdit(edit3));
783: assertEquals(3, um.indexOfNextAdd);
784: um.undo();
785: um.undo();
786: // moved indexOfNextAdd from 3 to 1
787: assertEquals(1, um.indexOfNextAdd);
788: TestUndoableEdit replaceEdit = new TestUndoableEdit();
789: assertTrue(um.addEdit(replaceEdit));
790: // must be called:
791: // 1) edit3.die
792: // 2) edit2.die
793: }
794:
795: @Override
796: public void testEditsCapacity() { // Regression for HARMONY-2649
797: assertEquals(100, um.edits.capacity());
798: }
799: }
|