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 Alexey A. Ivanov
019: * @version $Revision$
020: */package javax.swing.text;
021:
022: import javax.swing.text.AbstractDocument.DefaultDocumentEvent;
023: import javax.swing.text.AbstractDocument.ElementEdit;
024: import javax.swing.undo.CannotRedoException;
025: import javax.swing.undo.CannotUndoException;
026: import junit.framework.TestCase;
027:
028: /**
029: * All test methods should take into account that start and end positions of
030: * an element are moved as the document is mutated (text is changed).
031: *
032: */
033: public class AbstractDocument_ElementEditTest extends TestCase {
034: AbstractDocument doc;
035:
036: DefaultDocumentEvent insert;
037:
038: DefaultDocumentEvent remove;
039:
040: ElementEdit insertEdit;
041:
042: ElementEdit removeEdit;
043:
044: Element root;
045:
046: /*
047: * @see TestCase#setUp()
048: */
049: @Override
050: protected void setUp() throws Exception {
051: super .setUp();
052: doc = new PlainDocument() {
053: private static final long serialVersionUID = 1L;
054:
055: @Override
056: protected void insertUpdate(
057: final DefaultDocumentEvent event,
058: final AttributeSet attrs) {
059: insert = event;
060: //if (getName() == "testGetChildrenRemoved")
061: // System.out.println(getName());
062: super .insertUpdate(event, attrs);
063: insertEdit = (ElementEdit) insert.getChange(root);
064: }
065:
066: @Override
067: protected void removeUpdate(final DefaultDocumentEvent event) {
068: remove = event;
069: super .removeUpdate(event);
070: }
071:
072: @Override
073: protected void postRemoveUpdate(
074: final DefaultDocumentEvent event) {
075: assertSame(remove, event);
076: assertNull(remove.getChange(root));
077: super .postRemoveUpdate(event);
078: removeEdit = (ElementEdit) remove.getChange(root);
079: }
080: };
081: root = doc.getBidiRootElement();
082: doc.insertString(0, "01234" + "\u05DC\u05DD\u05DE\u05DF\u05E0",
083: null);
084: doc.remove(3, 4);
085: }
086:
087: public void testUndo01() throws BadLocationException {
088: removeEdit.undo();
089: assertEquals(2, root.getElementCount());
090: assertEquals(2, getBidiLevel(root.getElement(0)));
091: assertEquals(1, getBidiLevel(root.getElement(1)));
092: insertEdit.undo();
093: assertEquals(1, root.getElementCount());
094: assertEquals(0, getBidiLevel(root.getElement(0)));
095: // The text is not affected with these undoes
096: assertEquals("012\u05DE\u05DF\u05E0", doc.getText(0, doc
097: .getLength()));
098: try {
099: insertEdit.undo();
100: fail("CannotUndoException should be thrown");
101: } catch (CannotUndoException e) {
102: }
103: }
104:
105: /**
106: * Tests that added and removed children change places when undoing and
107: * redoing document structure changes.
108: */
109: public void testUndo02() throws BadLocationException {
110: Element[] added = removeEdit.getChildrenAdded();
111: Element[] removed = removeEdit.getChildrenRemoved();
112: removeEdit.undo();
113: // The added and removed children must change their places after undo
114: assertSame(added, removeEdit.getChildrenRemoved());
115: assertSame(removed, removeEdit.getChildrenAdded());
116: removeEdit.redo();
117: // The children must return to thier places after redo
118: assertSame(added, removeEdit.getChildrenAdded());
119: assertSame(removed, removeEdit.getChildrenRemoved());
120: }
121:
122: public void testRedo() throws BadLocationException {
123: removeEdit.undo();
124: insertEdit.undo();
125: assertEquals(1, root.getElementCount());
126: assertEquals(0, getBidiLevel(root.getElement(0)));
127: // The text is not affected with these undoes
128: assertEquals("012\u05DE\u05DF\u05E0", doc.getText(0, doc
129: .getLength()));
130: insertEdit.redo();
131: assertEquals(2, root.getElementCount());
132: assertEquals(2, getBidiLevel(root.getElement(0)));
133: assertEquals(1, getBidiLevel(root.getElement(1)));
134: removeEdit.redo();
135: assertEquals(2, root.getElementCount());
136: assertEquals(2, getBidiLevel(root.getElement(0)));
137: assertEquals(1, getBidiLevel(root.getElement(1)));
138: try {
139: removeEdit.redo();
140: fail("CannotRedoException should be thrown");
141: } catch (CannotRedoException e) {
142: }
143: }
144:
145: public void testElementEdit() {
146: Element[] inserted = new Element[] {
147: doc.new BranchElement(null, null),
148: doc.new BranchElement(null, null) };
149: Element[] removed = new Element[] {
150: doc.new LeafElement(null, null, 0, 1),
151: doc.new LeafElement(null, null, 1, 2),
152: doc.new LeafElement(null, null, 2, 3), };
153: AbstractDocument.ElementEdit edit = new AbstractDocument.ElementEdit(
154: doc.getBidiRootElement(), 1, removed, inserted);
155: assertSame(doc.getBidiRootElement(), edit.getElement());
156: assertSame(inserted, edit.getChildrenAdded());
157: assertSame(removed, edit.getChildrenRemoved());
158: assertEquals(1, edit.getIndex());
159: }
160:
161: private static int getBidiLevel(final Element e) {
162: return ((Integer) e.getAttributes().getAttribute(
163: StyleConstants.BidiLevel)).intValue();
164: }
165:
166: public void testGetChildrenRemoved() {
167: Element[] removed = insertEdit.getChildrenRemoved();
168: assertEquals(1, removed.length);
169: assertTrue(removed[0].isLeaf());
170: assertEquals(0, removed[0].getStartOffset());
171: // The last position in the document became 7 after remove (was 1, 11)
172: assertEquals(7, removed[0].getEndOffset());
173: assertEquals(0, getBidiLevel(removed[0]));
174: //((AbstractElement)removed[0]).dump(System.out, 0);
175: removed = removeEdit.getChildrenRemoved();
176: assertEquals(2, removed.length);
177: assertTrue(removed[0].isLeaf());
178: assertEquals(0, removed[0].getStartOffset());
179: // The position between two text direction is 3 after remove (was 5)
180: assertEquals(3, removed[0].getEndOffset());
181: // The sequence of numeral gets level 2 (it seems like the
182: // bidi-algorithm considers them embedded in a RTL run).
183: assertEquals(2, getBidiLevel(removed[0]));
184: assertTrue(removed[1].isLeaf());
185: assertEquals(3, removed[1].getStartOffset());
186: assertEquals(7, removed[1].getEndOffset());
187: assertEquals(1, getBidiLevel(removed[1]));
188: }
189:
190: public void testGetChildrenAdded() {
191: Element[] added = insertEdit.getChildrenAdded();
192: assertEquals(2, added.length);
193: assertTrue(added[0].isLeaf());
194: assertEquals(0, added[0].getStartOffset());
195: assertEquals(3, added[0].getEndOffset());
196: assertEquals(2, getBidiLevel(added[0]));
197: assertTrue(added[1].isLeaf());
198: assertEquals(3, added[1].getStartOffset());
199: assertEquals(7, added[1].getEndOffset());
200: assertEquals(1, getBidiLevel(added[1]));
201: added = removeEdit.getChildrenAdded();
202: assertEquals(2, added.length);
203: assertTrue(added[0].isLeaf());
204: assertEquals(0, added[0].getStartOffset());
205: assertEquals(3, added[0].getEndOffset());
206: assertEquals(2, getBidiLevel(added[0]));
207: assertTrue(added[1].isLeaf());
208: assertEquals(3, added[1].getStartOffset());
209: assertEquals(7, added[1].getEndOffset());
210: assertEquals(1, getBidiLevel(added[1]));
211: }
212:
213: public void testGetElement() {
214: assertSame(root, insertEdit.getElement());
215: assertSame(root, removeEdit.getElement());
216: }
217:
218: public void testGetIndex() throws BadLocationException {
219: assertEquals(0, insertEdit.getIndex());
220: assertEquals(0, removeEdit.getIndex());
221: doc.insertString(6, "\nab\ncd\ne", null);
222: doc.insertString(doc.getLength(), "\nnew line", null);
223: AbstractDocument.ElementEdit e = (AbstractDocument.ElementEdit) insert
224: .getChange(doc.getDefaultRootElement());
225: // We've inserted 4 paragraphs of text, then indexes of elements
226: // representing them are 0 - 3. When we insert a new paragraph, the
227: // element representing the latest paragraph is modified. Hence it
228: // is removed and then added again. (Also a new paragraph is added
229: // during this process.)
230: // Thus the index should be 3 since the first element modified is at 3.
231: assertEquals(3, e.getIndex());
232: }
233: }
|