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 java.io.ByteArrayOutputStream;
023: import java.io.PrintStream;
024: import java.util.Dictionary;
025: import java.util.Enumeration;
026: import java.util.Hashtable;
027: import javax.swing.BasicSwingTestCase;
028: import javax.swing.event.DocumentEvent;
029: import javax.swing.event.DocumentListener;
030: import javax.swing.text.AbstractDocument.BranchElement;
031: import javax.swing.text.AbstractDocument.LeafElement;
032: import junit.framework.TestCase;
033: import org.apache.harmony.x.swing.StringConstants;
034:
035: /**
036: * Tests functionality of AbstractDocument class.
037: *
038: */
039: public class AbstractDocumentTest extends TestCase {
040: /**
041: * The content of the document.
042: * (Implementation of AbstractDocument.Content)
043: */
044: private static GapContent content;
045:
046: /**
047: * Shared document object.
048: */
049: private static AbstractDocument doc;
050:
051: /**
052: * Document property keys.
053: */
054: static Integer[] keys = new Integer[] { new Integer(1),
055: new Integer(2), new Integer(3) };
056:
057: /**
058: * Document property values.
059: */
060: static String[] values = new String[] { "one", "two", "three" };
061:
062: /**
063: * Initializes fixture for tests.
064: */
065: @Override
066: protected void setUp() throws Exception {
067: super .setUp();
068: doc = new DisAbstractedDocument(content = new GapContent());
069: }
070:
071: /**
072: * Implements abstract methods of AbstractDocument without changing
073: * any other.
074: */
075: protected static class DisAbstractedDocument extends
076: AbstractDocument {
077: private static final long serialVersionUID = 1L;
078:
079: protected DisAbstractedDocument(final Content content) {
080: super (content);
081: createRoot();
082: }
083:
084: public DisAbstractedDocument(final Content content,
085: final AttributeContext context) {
086: super (content, context);
087: createRoot();
088: }
089:
090: private BranchElement defRoot;
091:
092: protected void createRoot() {
093: writeLock();
094: defRoot = new BranchElement(null, null);
095: defRoot.replace(0, 0, new Element[] { new LeafElement(
096: defRoot, null, 0, 1) });
097: writeUnlock();
098: }
099:
100: @Override
101: public Element getParagraphElement(final int offset) {
102: return defRoot.getElement(0);
103: }
104:
105: @Override
106: public Element getDefaultRootElement() {
107: return defRoot;
108: }
109: }
110:
111: /**
112: * Tests constructor
113: * AbstractDocument(AbstractDocument.Content,
114: * AbstractDocument.AttributeContext)
115: */
116: public void testAbstractDocumentContentAttributeContext() {
117: GapContent content = new GapContent();
118: StyleContext context = new StyleContext();
119: AbstractDocument doc = new DisAbstractedDocument(content,
120: context);
121: assertSame(content, doc.getContent());
122: assertSame(context, doc.getAttributeContext());
123: Object BidiProperty = BasicSwingTestCase.isHarmony() ? StringConstants.BIDI_PROPERTY
124: : "i18n";
125: assertTrue(doc.getProperty(BidiProperty).equals(Boolean.FALSE));
126: }
127:
128: /**
129: * Tests constructor AbstractDocument(AbstractDocument.Content)
130: */
131: public void testAbstractDocumentContent() {
132: GapContent content = new GapContent();
133: AbstractDocument doc = new DisAbstractedDocument(content);
134: assertSame(content, doc.getContent());
135: assertSame(StyleContext.getDefaultStyleContext(), doc
136: .getAttributeContext());
137: }
138:
139: public void testBAD_LOCATION() {
140: assertEquals("document location failure",
141: AbstractDocument.BAD_LOCATION);
142: }
143:
144: public void testCreateLeafElement() throws BadLocationException {
145: Element leaf = doc.createLeafElement(null, null, 0, 1);
146: assertTrue(leaf instanceof LeafElement);
147: assertNull(leaf.getParentElement());
148: assertEquals(0, leaf.getStartOffset());
149: assertEquals(1, leaf.getEndOffset());
150: doc.insertString(0, "01234", null);
151: Element leaf2 = doc.createLeafElement(leaf, null, 1, 3);
152: assertTrue(leaf2 instanceof LeafElement);
153: assertSame(leaf, leaf2.getParentElement());
154: assertEquals(1, leaf2.getStartOffset());
155: assertEquals(3, leaf2.getEndOffset());
156: doc.remove(0, 5);
157: assertEquals(0, leaf2.getStartOffset());
158: assertEquals(0, leaf2.getEndOffset());
159: }
160:
161: public void testCreateBranchElement() {
162: Element branch = doc.createBranchElement(null, null);
163: assertTrue(branch instanceof BranchElement);
164: assertNull(branch.getParentElement());
165: assertNull(branch.getElement(0));
166: assertNull(branch.getElement(1));
167: assertEquals(0, branch.getElementCount());
168:
169: // Since this branch element has no children yet, it has no start and
170: // end offsets. Thus calling get{Start,End}Offset on an empty branch
171: // element causes the exception being thrown.
172: try {
173: assertEquals(0, branch.getStartOffset());
174: fail("getStartOffset is expected to throw NullPointerException");
175: } catch (NullPointerException e) {
176: }
177:
178: try {
179: assertEquals(1, branch.getEndOffset());
180: fail("getEndOffset is expected to throw NullPointerException");
181: } catch (NullPointerException e) {
182: }
183: }
184:
185: /**
186: * Tests method insertString.
187: */
188: public void testInsertString01() throws BadLocationException {
189: int length = doc.getLength();
190: assertEquals(0, length);
191: assertEquals("", doc.getText(0, length));
192: doc.insertString(0, "01234", null);
193: length = doc.getLength();
194: assertEquals(5, length);
195: assertEquals("01234", doc.getText(0, length));
196: try {
197: doc.insertString(-1, "invalid", null);
198: fail("BadLocationException should be thrown");
199: } catch (BadLocationException e) {
200: }
201: }
202:
203: /**
204: * Tests method insertString when passing null as text.
205: */
206: public void testInsertString02() throws BadLocationException {
207: int length = doc.getLength();
208: assertEquals(0, length);
209: assertEquals("", doc.getText(0, length));
210: doc.insertString(0, null, null);
211: // Try to insert null at inappropriate position
212: doc.insertString(-1, null, null);
213: }
214:
215: public void testRemove() throws BadLocationException {
216: doc.insertString(0, "01234", null);
217: doc.remove(1, 2);
218: assertEquals("034", doc.getText(0, doc.getLength()));
219: // Invalid offset into the model but remove length is zero - nothing
220: // is done (no exception)
221: doc.remove(-1, 0);
222: // Invalid offset and non-zero remove length - exception is thrown
223: try {
224: doc.remove(-1, 1);
225: fail("BadLocationException 'invalid offset' should be thrown");
226: } catch (BadLocationException e) {
227: }
228: // Invalid length
229: try {
230: doc.remove(0, 4);
231: fail("BadLocationException 'invalid length' should be thrown");
232: } catch (BadLocationException e) {
233: }
234: }
235:
236: /**
237: * General functionality tests for replace.
238: */
239: public void testReplace01() throws BadLocationException {
240: doc.insertString(0, "01234", null);
241: doc.replace(1, 2, "abcde", null);
242: assertEquals("0abcde34", doc.getText(0, doc.getLength()));
243: doc.replace(0, 5, null, null);
244: assertEquals("e34", doc.getText(0, doc.getLength()));
245: doc.replace(0, 2, "", null);
246: assertEquals("4", doc.getText(0, doc.getLength()));
247: // Invalid offset into the model
248: try {
249: doc.replace(-1, 0, "some text", null);
250: fail("BadLocationException 'invalid offset' should be thrown");
251: } catch (BadLocationException e) {
252: }
253: // Invalid length
254: try {
255: doc.replace(0, 4, "some text", null);
256: fail("BadLocationException 'invalid length' should be thrown");
257: } catch (BadLocationException e) {
258: }
259: }
260:
261: /**
262: * Tests that insert listener is not called when calling replace with
263: * null or empty text to insert.
264: */
265: public void testReplace02() throws BadLocationException {
266: doc.insertString(0, "01234", null);
267: final class DocListener implements DocumentListener {
268: private boolean insert = false;
269:
270: private boolean remove = false;
271:
272: public void changedUpdate(final DocumentEvent event) {
273: fail("changedUpdate is not expected to be called");
274: }
275:
276: public void insertUpdate(final DocumentEvent event) {
277: insert = true;
278: }
279:
280: public void removeUpdate(final DocumentEvent event) {
281: remove = true;
282: }
283:
284: public void check(final boolean eInsert,
285: final boolean eRemove) {
286: assertEquals(eInsert, insert);
287: assertEquals(eRemove, remove);
288: insert = remove = false;
289: }
290: }
291: DocListener listener = new DocListener();
292: doc.addDocumentListener(listener);
293: doc.replace(0, 2, null, null);
294: assertEquals("234", doc.getText(0, doc.getLength()));
295: listener.check(false, true);
296: doc.replace(0, 2, "", null);
297: assertEquals("4", doc.getText(0, doc.getLength()));
298: listener.check(false, true);
299: doc.replace(0, 0, "", null);
300: listener.check(false, false);
301: }
302:
303: /**
304: * Tests methods putProperty and getProperty.
305: */
306: public void testPutGetProperty() {
307: for (int i = 0; i < keys.length; i++) {
308: doc.putProperty(keys[i], values[i]);
309: }
310: // Check
311: for (int i = 0; i < keys.length; i++) {
312: assertEquals(values[i], doc.getProperty(keys[i]));
313: }
314: // Test property removal
315: doc.putProperty(keys[0], null);
316: assertNull(doc.getProperty(keys[0]));
317: }
318:
319: /**
320: * Tests method void getText(int, int, Segment).
321: */
322: public void testGetTextintintSegment() throws BadLocationException {
323: Segment txt = new Segment();
324: doc.insertString(0, "01234abcde", null);
325: doc.insertString(5, "!", null);
326: doc.getText(0, 5, txt);
327: assertEquals("01234", txt.toString());
328: assertEquals(0, txt.offset);
329: assertEquals(5, txt.count);
330: assertSame(content.getArray(), txt.array);
331: doc.getText(6, 5, txt);
332: assertEquals("abcde", txt.toString());
333: int gapLength = content.getGapEnd() - content.getGapStart();
334: assertEquals(6 + gapLength, txt.offset);
335: assertEquals(5, txt.count);
336: assertSame(content.getArray(), txt.array);
337: doc.getText(0, 11, txt);
338: assertEquals("01234!abcde", txt.toString());
339: assertEquals(0, txt.offset);
340: assertEquals(11, txt.count);
341: assertNotSame(content.getArray(), txt.array);
342: txt.setPartialReturn(true);
343: doc.getText(0, 11, txt);
344: assertEquals("01234!", txt.toString());
345: assertEquals(0, txt.offset);
346: assertEquals(6, txt.count);
347: assertSame(content.getArray(), txt.array);
348: try {
349: doc.getText(-1, 5, txt);
350: fail("BadLocationException: \"invalid offset\" must be thrown.");
351: } catch (BadLocationException e) {
352: }
353: try {
354: doc.getText(12, 1, txt);
355: fail("BadLocationException: \"invalid offset\" must be thrown.");
356: } catch (BadLocationException e) {
357: }
358: try {
359: doc.getText(0, 13, txt);
360: fail("BadLocationException: \"invalid length\" must be thrown.");
361: } catch (BadLocationException e) {
362: }
363: }
364:
365: /**
366: * Tests method String getText(int, int).
367: */
368: public void testGetTextintint() throws BadLocationException {
369: doc.insertString(0, "01234abcde", null);
370: doc.insertString(5, "!", null);
371: // before the gap
372: assertEquals("01234", doc.getText(0, 5));
373: // after the gap
374: assertEquals("abcde", doc.getText(6, 5));
375: // the gap is the middle
376: assertEquals("01234!abcde", doc.getText(0, 11));
377: try {
378: doc.getText(-1, 5);
379: fail("BadLocationException: \"invalid offset\" must be thrown.");
380: } catch (BadLocationException e) {
381: }
382: try {
383: doc.getText(12, 1);
384: fail("BadLocationException: \"invalid offset\" must be thrown.");
385: } catch (BadLocationException e) {
386: }
387: try {
388: doc.getText(0, 13);
389: fail("BadLocationException: \"invalid length\" must be thrown.");
390: } catch (BadLocationException e) {
391: }
392: }
393:
394: /**
395: * Tests createPosition method.
396: */
397: public void testCreatePosition() throws BadLocationException {
398: try {
399: doc.createPosition(-2);
400: if (BasicSwingTestCase.isHarmony()) {
401: fail("BadLocationException should be thrown");
402: }
403: } catch (BadLocationException e) {
404: }
405: Position pos0 = doc.createPosition(0);
406: Position pos5 = doc.createPosition(5);
407: assertEquals(0, pos0.getOffset());
408: assertEquals(5, pos5.getOffset());
409: doc.insertString(0, "01234", null);
410: assertEquals(0, pos0.getOffset());
411: assertEquals(10, pos5.getOffset());
412: }
413:
414: /**
415: * Tests both methods at once: getStartPosition and getEndPosition
416: * @throws BadLocationException
417: */
418: public void testGetStartEndPosition() throws BadLocationException {
419: Position start = doc.getStartPosition();
420: Position end = doc.getEndPosition();
421: assertEquals(0, start.getOffset());
422: assertEquals(1, end.getOffset());
423: doc.insertString(0, "01234", null);
424: assertEquals(0, start.getOffset());
425: assertEquals(6, end.getOffset());
426: doc.insertString(2, "abcde", null);
427: assertEquals(0, start.getOffset());
428: assertEquals(11, end.getOffset());
429: assertSame(start, doc.getStartPosition());
430: assertSame(end, doc.getEndPosition());
431: doc.remove(0, 6);
432: assertEquals("e234", doc.getText(0, doc.getLength()));
433: assertEquals(0, start.getOffset());
434: assertEquals(5, end.getOffset());
435: }
436:
437: public void testGetRootElements() {
438: Element[] roots = doc.getRootElements();
439: assertEquals(2, roots.length);
440: assertNotNull(roots[0]);
441: assertSame(roots[0], doc.getDefaultRootElement());
442: assertNotNull(roots[1]);
443: assertSame(roots[1], doc.getBidiRootElement());
444: }
445:
446: public void testGetBidiRootElement() {
447: Element root = doc.getBidiRootElement();
448: assertNotNull(root);
449: assertTrue(root instanceof BranchElement);
450: assertEquals("bidi root", root.getName());
451: assertEquals(0, root.getStartOffset());
452: assertEquals(1, root.getEndOffset());
453: Enumeration<?> elements = ((BranchElement) root).children();
454: Element element = null;
455: int count = 0;
456: while (elements.hasMoreElements()) {
457: count++;
458: element = (Element) elements.nextElement();
459: }
460: // if the document is empty there should be only one child
461: assertEquals(1, count);
462: assertTrue(element instanceof LeafElement);
463: assertEquals("bidi level", element.getName());
464: assertSame(AbstractDocument.BidiElementName, element.getName());
465: assertEquals(0, element.getStartOffset());
466: assertEquals(1, element.getEndOffset());
467: }
468:
469: public void testGetContent() {
470: assertSame(content, doc.getContent());
471: }
472:
473: public void testGetAttributeContext() {
474: assertSame(StyleContext.getDefaultStyleContext(), doc
475: .getAttributeContext());
476: }
477:
478: public void testSetGetDocumentProperties() {
479: Hashtable<Object, Object> table = new Hashtable<Object, Object>();
480: for (int i = 0; i < keys.length; i++) {
481: table.put(keys[i], values[i]);
482: }
483: assertNotSame(table, doc.getDocumentProperties());
484: doc.setDocumentProperties(table);
485: assertSame(table, doc.getDocumentProperties());
486: for (int i = 0; i < keys.length; i++) {
487: assertEquals(values[i], doc.getProperty(keys[i]));
488: }
489: }
490:
491: public void testDump() {
492: ByteArrayOutputStream out = new ByteArrayOutputStream();
493: doc.dump(new PrintStream(out));
494: assertEquals("<paragraph>\n" + " <content>\n" + " [0,1][\n"
495: + "]\n" + "<bidi root>\n" + " <bidi level\n"
496: + " bidiLevel=0\n" + " >\n" + " [0,1][\n"
497: + "]\n", filterNewLines(out.toString()));
498: }
499:
500: public static String filterNewLines(final String str) {
501: return str.replaceAll("\r\n", "\n").replaceAll("\r", "\n");
502: }
503:
504: /**
505: * Tests setDocumentFilter and getDocumentFilter methods.
506: */
507: public void testSetGetDocumentFilter() {
508: assertNull(doc.getDocumentFilter());
509: DocumentFilter filter = new DocumentFilter();
510: doc.setDocumentFilter(filter);
511: assertSame(filter, doc.getDocumentFilter());
512: }
513:
514: public void testGetLength() throws BadLocationException {
515: int length = doc.getLength();
516: assertEquals(0, length);
517: doc.insertString(0, "01234", null);
518: length = doc.getLength();
519: assertEquals(5, length);
520: }
521:
522: /**
523: * Tests setAsynchronousLoadPriority and getAsynchronousLoadPriority
524: * methods.
525: */
526: public void testSetGetAsynchronousLoadPriority() {
527: // Test the default
528: assertEquals(-1, doc.getAsynchronousLoadPriority());
529: // Change the default
530: doc.setAsynchronousLoadPriority(10);
531: assertEquals(10, doc.getAsynchronousLoadPriority());
532: }
533:
534: /**
535: * Tests setAsynchronousLoadPriority and getAsynchronousLoadPriority
536: * methods: it asserts they use document property.
537: */
538: public void testSetGetAsynchronousLoadPriority02() {
539: final String key = "load priority";
540: final Dictionary<?, ?> properties = doc.getDocumentProperties();
541: assertEquals(1, properties.size());
542: assertNotNull(properties.get("i18n"));
543: // Test the default
544: assertEquals(-1, doc.getAsynchronousLoadPriority());
545: // Change the default
546: assertNull(doc.getProperty(key));
547: doc.setAsynchronousLoadPriority(10);
548: assertEquals(2, properties.size());
549: Object value = doc.getProperty(key);
550: assertTrue(value instanceof Integer);
551: assertEquals(10, ((Integer) value).intValue());
552: assertEquals(10, doc.getAsynchronousLoadPriority());
553: doc.putProperty(key, new Integer(-255));
554: assertEquals(-255, doc.getAsynchronousLoadPriority());
555: doc.putProperty(key, "123");
556: if (BasicSwingTestCase.isHarmony()) {
557: assertEquals(-1, doc.getAsynchronousLoadPriority());
558: } else {
559: try {
560: doc.getAsynchronousLoadPriority();
561: fail("ClassCastException is expected");
562: } catch (ClassCastException e) {
563: }
564: }
565: doc.putProperty(key, null);
566: assertEquals(1, properties.size());
567: assertEquals(-1, doc.getAsynchronousLoadPriority());
568: }
569: }
|