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, Roman I. Chernyatchik
019: * @version $Revision$
020: */package javax.swing.text;
021:
022: import java.lang.ref.Reference;
023: import java.lang.ref.ReferenceQueue;
024: import java.lang.ref.WeakReference;
025: import java.util.Vector;
026: import javax.swing.undo.UndoableEdit;
027:
028: /**
029: * Tests StringContent class.
030: *
031: */
032: public class StringContentTest extends AbstractDocument_ContentTest {
033: private StringContent content;
034:
035: @Override
036: protected void setUp() throws Exception {
037: super .setUp();
038: obj = new StringContent();
039: obj.insertString(0, "This is a test string.");
040: content = new StringContent();
041: content.insertString(0, "012345");
042: }
043:
044: @Override
045: public void testGetCharsNegativeLength() {
046: if (isHarmony()) {
047: testExceptionalCase(new BadLocationCase() {
048: @Override
049: public void exceptionalAction() throws Exception {
050: obj.getChars(0, -2, new Segment());
051: }
052:
053: @Override
054: public String expectedExceptionMessage() {
055: return "Length must be non-negative";
056: }
057: });
058: } else {
059: try {
060: obj.getChars(0, -2, new Segment());
061: } catch (BadLocationException e) {
062: }
063: }
064: }
065:
066: @Override
067: public void testGetCharsPartial() throws BadLocationException {
068: obj.insertString(10, "big ");
069: text.setPartialReturn(true);
070: obj.getChars(8, 10, text);
071: assertEquals("a big test", text.toString());
072: }
073:
074: @Override
075: public void testGetStringNegativeLength() {
076: if (isHarmony()) {
077: testExceptionalCase(new BadLocationCase() {
078: @Override
079: public void exceptionalAction() throws Exception {
080: obj.getString(0, -2);
081: }
082:
083: @Override
084: public String expectedExceptionMessage() {
085: return "Length must be non-negative";
086: }
087: });
088: } else {
089: testExceptionalCase(new StringIndexOutOfBoundsCase() {
090: @Override
091: public void exceptionalAction() throws Exception {
092: obj.getString(0, -2);
093: }
094: });
095: }
096: }
097:
098: public void testStringContent() throws BadLocationException {
099: content = new StringContent();
100: assertEquals(1, content.length());
101: content.getChars(0, content.length(), text);
102: assertEquals("\n", text.toString());
103: assertEquals(10, text.array.length);
104: }
105:
106: public void testStringContent_WithValidValues()
107: throws BadLocationException {
108: content = new StringContent(20);
109: assertEquals(1, content.length());
110: content.getChars(0, content.length(), text);
111: assertEquals("\n", text.toString());
112: assertEquals(20, text.array.length);
113: }
114:
115: public void testStringContent_WithInvalidValues()
116: throws BadLocationException {
117: content = new StringContent(0);
118: assertEquals(1, content.length());
119: content.getChars(0, content.length(), text);
120: assertEquals("\n", text.toString());
121: assertEquals(1, text.array.length);
122: }
123:
124: public void testCreatePositionBeforeUndo()
125: throws BadLocationException {
126: UndoableEdit undoable;
127: content = new StringContent(10);
128: content.insertString(0, "0123456789");
129: undoable = content.remove(3, 5);
130: Position pos1 = content.createPosition(3);
131: assertEquals(3, pos1.getOffset());
132: undoable.undo();
133: content = new StringContent(10);
134: content.insertString(0, "0123456789");
135: undoable = content.remove(3, 5);
136: Position pos = content.createPosition(3);
137: assertEquals(3, pos.getOffset());
138: undoable.undo();
139: assertEquals(8, pos.getOffset());
140: undoable.redo();
141: assertEquals(3, pos.getOffset());
142: }
143:
144: public void testCreatePositionAfterUndone()
145: throws BadLocationException {
146: UndoableEdit undoable;
147: content = new StringContent(10);
148: content.insertString(0, "0123456789");
149: undoable = content.remove(3, 5);
150: undoable.undo();
151: Position pos = content.createPosition(5);
152: assertEquals(5, pos.getOffset());
153: undoable.redo();
154: assertEquals(3, pos.getOffset());
155: undoable.undo();
156: assertEquals(5, pos.getOffset());
157: }
158:
159: public void testCreatePositionAfterInsert()
160: throws BadLocationException {
161: UndoableEdit undoable;
162: content = new StringContent(10);
163: content.insertString(0, "0123456789");
164: undoable = content.insertString(10, "big ");
165: Position pos = content.createPosition(12);
166: assertEquals(12, pos.getOffset());
167: undoable.undo();
168: assertEquals(10, pos.getOffset());
169: undoable.redo();
170: assertEquals(12, pos.getOffset());
171: }
172:
173: public void testCreatePosition_WithInvalidValues()
174: throws BadLocationException {
175: content = new StringContent(10);
176: content.insertString(0, "012345");
177: if (isHarmony()) {
178: testExceptionalCase(new BadLocationCase() {
179: @Override
180: public void exceptionalAction() throws Exception {
181: content.createPosition(-1);
182: }
183:
184: @Override
185: public String expectedExceptionMessage() {
186: return "Invalid position offset";
187: }
188: });
189: } else {
190: content.createPosition(-1);
191: }
192: content.createPosition(12);
193: }
194:
195: public void testGetChars_WithValidValues()
196: throws BadLocationException {
197: content = new StringContent();
198: content.getChars(0, 1, text);
199: content.getChars(0, 0, text);
200: content.getChars(0, content.length(), text);
201: assertEquals("\n", text.toString());
202: assertEquals(10, text.array.length);
203: }
204:
205: public void testGetChars_WithInvalidValues()
206: throws BadLocationException {
207: content = new StringContent();
208: if (isHarmony()) {
209: testExceptionalCase(new BadLocationCase() {
210: @Override
211: public void exceptionalAction() throws Exception {
212: content.getChars(-5, 1, text);
213: }
214:
215: @Override
216: public String expectedExceptionMessage() {
217: return "Invalid start position";
218: }
219: });
220: } else {
221: content.getChars(-5, 1, text);
222: }
223: testExceptionalCase(new BadLocationCase() {
224: @Override
225: public void exceptionalAction() throws Exception {
226: content.getChars(0, 2, text);
227: }
228: });
229: if (isHarmony()) {
230: testExceptionalCase(new BadLocationCase() {
231: @Override
232: public void exceptionalAction() throws Exception {
233: content.getChars(0, -2, text);
234: }
235:
236: @Override
237: public String expectedExceptionMessage() {
238: return "Length must be non-negative";
239: }
240: });
241: } else {
242: content.getChars(0, -2, text);
243: }
244: }
245:
246: public void testGetPositionsInRangeVector()
247: throws BadLocationException {
248: Vector<Object> v = new Vector<Object>();
249: v.add(new Object());
250: v.add(new Object());
251: content.createPosition(0);
252: content.createPosition(1);
253: content.createPosition(2);
254: content.getPositionsInRange(v, 0, 3);
255: if (isHarmony()) {
256: // Position at offset 0 WILL NOT be included
257: assertEquals(4, v.size());
258: } else {
259: // Position at offset 0 WILL be included
260: assertEquals(5, v.size());
261: }
262: }
263:
264: public void testGetPositionsInRange() throws BadLocationException {
265: content.createPosition(10);
266: Vector<?> v = content.getPositionsInRange(null, 0, 10);
267: assertEquals(1, v.size());
268: }
269:
270: public void testGetString_WithValidValues()
271: throws BadLocationException {
272: content.getString(0, 0);
273: content.getString(0, content.length());
274: }
275:
276: public void testGetString_WithInValidValues()
277: throws BadLocationException {
278: testExceptionalCase(new BadLocationCase() {
279: @Override
280: public void exceptionalAction() throws Exception {
281: content.getString(0, content.length() + 1);
282: }
283: });
284: testExceptionalCase(new BadLocationCase() {
285: @Override
286: public void exceptionalAction() throws Exception {
287: content.getString(0, content.length() + 5);
288: }
289: });
290: if (isHarmony()) {
291: testExceptionalCase(new BadLocationCase() {
292: @Override
293: public void exceptionalAction() throws Exception {
294: content.getString(-1, content.length() - 2);
295: }
296: });
297: } else {
298: testExceptionalCase(new StringIndexOutOfBoundsCase() {
299: @Override
300: public void exceptionalAction() throws Exception {
301: content.getString(-1, content.length() - 2);
302: }
303: });
304: }
305: if (isHarmony()) {
306: testExceptionalCase(new BadLocationCase() {
307: @Override
308: public void exceptionalAction() throws Exception {
309: content.getString(1, -1);
310: }
311: });
312: } else {
313: testExceptionalCase(new StringIndexOutOfBoundsCase() {
314: @Override
315: public void exceptionalAction() throws Exception {
316: content.getString(1, -1);
317: }
318: });
319: }
320: }
321:
322: public void testInsertString_WithValidValues()
323: throws BadLocationException {
324: UndoableEdit ue = content.insertString(2, "^^^");
325: assertNotNull(ue);
326: content.getChars(0, content.length(), text);
327: assertEquals(20, text.array.length);
328: assertEquals("01^^^2345\n", content.getString(0, content
329: .length()));
330: ue.undo();
331: assertEquals("012345\n", content.getString(0, content.length()));
332: ue.redo();
333: assertEquals("01^^^2345\n", content.getString(0, content
334: .length()));
335: }
336:
337: public void testInsertString_WithInvalidValues()
338: throws BadLocationException {
339: content = new StringContent();
340: testExceptionalCase(new BadLocationCase() {
341: @Override
342: public void exceptionalAction() throws Exception {
343: content.insertString(-1, "12345");
344: }
345: });
346: testExceptionalCase(new BadLocationCase() {
347: @Override
348: public void exceptionalAction() throws Exception {
349: content.insertString(1, "12345");
350: }
351: });
352: testExceptionalCase(new NullPointerCase() {
353: @Override
354: public void exceptionalAction() throws Exception {
355: content.insertString(0, null);
356: }
357: });
358: }
359:
360: public void testInsertString_UndoableEdit()
361: throws BadLocationException {
362: UndoableEdit undoable;
363: final String redoName = isHarmony() ? "Redo addition" : "Redo";
364: final String undoName = isHarmony() ? "Undo addition" : "Undo";
365: undoable = content.insertString(0, "012345");
366: assertEquals(redoName, undoable.getRedoPresentationName());
367: assertEquals(undoName, undoable.getUndoPresentationName());
368: assertTrue(undoable.isSignificant());
369: assertFalse(undoable.canRedo());
370: assertTrue(undoable.canUndo());
371: undoable.undo();
372: assertTrue(undoable.canRedo());
373: assertFalse(undoable.canUndo());
374: undoable.redo();
375: assertFalse(undoable.canRedo());
376: assertTrue(undoable.canUndo());
377: assertFalse(undoable.addEdit(null));
378: assertFalse(undoable.addEdit(undoable));
379: }
380:
381: public void testRemove_WithValidValues()
382: throws BadLocationException {
383: content = new StringContent();
384: content.insertString(0, "012345^11111");
385: content.getChars(0, content.length(), text);
386: assertEquals(13, text.count);
387: assertEquals(20, text.array.length);
388: UndoableEdit undoable = content.remove(2, 0);
389: content.getChars(0, content.length(), text);
390: assertEquals(13, text.count);
391: assertEquals(20, text.array.length);
392: assertNotNull(undoable);
393: assertEquals("012345^11111\n", content.getString(0, content
394: .length()));
395: undoable = content.remove(2, 5);
396: content.getChars(0, content.length(), text);
397: assertEquals(8, text.count);
398: assertEquals(20, text.array.length);
399: assertNotNull(undoable);
400: assertEquals("0111111\n", content
401: .getString(0, content.length()));
402: undoable.undo();
403: assertEquals("012345^11111\n", content.getString(0, content
404: .length()));
405: undoable.redo();
406: assertEquals("0111111\n", content
407: .getString(0, content.length()));
408: }
409:
410: public void testRemove_UndoableEdit() throws BadLocationException {
411: UndoableEdit undoable = content.remove(2, 3);
412: final String redoName = isHarmony() ? "Redo deletion" : "Redo";
413: final String undoName = isHarmony() ? "Undo deletion" : "Undo";
414: assertEquals(redoName, undoable.getRedoPresentationName());
415: assertEquals(undoName, undoable.getUndoPresentationName());
416: assertTrue(undoable.isSignificant());
417: assertFalse(undoable.canRedo());
418: assertTrue(undoable.canUndo());
419: assertEquals(redoName, undoable.getRedoPresentationName());
420: assertEquals(undoName, undoable.getUndoPresentationName());
421: assertTrue(undoable.isSignificant());
422: assertFalse(undoable.canRedo());
423: assertTrue(undoable.canUndo());
424: undoable.undo();
425: assertTrue(undoable.canRedo());
426: assertFalse(undoable.canUndo());
427: undoable.redo();
428: assertFalse(undoable.canRedo());
429: assertTrue(undoable.canUndo());
430: assertFalse(undoable.addEdit(null));
431: assertFalse(undoable.addEdit(undoable));
432: }
433:
434: public void testRemove_WithInvalidValues()
435: throws BadLocationException {
436: content = new StringContent();
437: content.insertString(0, "012345^11111");
438: content.getChars(0, content.length(), text);
439: assertEquals(13, text.count);
440: assertEquals(20, text.array.length);
441: UndoableEdit ue = content.remove(2, 5);
442: content.getChars(0, content.length(), text);
443: assertEquals(8, text.count);
444: assertEquals(20, text.array.length);
445: assertNotNull(ue);
446: assertEquals("0111111\n", content
447: .getString(0, content.length()));
448: ue.undo();
449: assertEquals("012345^11111\n", content.getString(0, content
450: .length()));
451: ue.redo();
452: assertEquals("0111111\n", content
453: .getString(0, content.length()));
454: }
455:
456: public void testPositionGC() throws BadLocationException {
457: Vector<WeakReference<Position>> pos = new Vector<WeakReference<Position>>(
458: 10);
459: ReferenceQueue<Position> rq = new ReferenceQueue<Position>();
460: for (int i = 0; i < content.length(); i += 2) {
461: pos.add(new WeakReference<Position>(content
462: .createPosition(i), rq));
463: }
464: int count = 0;
465: int i;
466: for (i = 0; i < 100; i++) {
467: System.gc();
468: Reference<?> r;
469: if ((r = rq.poll()) != null) {
470: pos.remove(r);
471: count++;
472: if (pos.size() == 0) {
473: return;
474: }
475: }
476: }
477: fail("Not all Position objects are removed (" + pos.size()
478: + "/" + count + ").");
479: }
480:
481: public void testLength_ForStringContent() throws Exception {
482: content = new StringContent();
483: assertEquals(1, content.length());
484: content.insertString(0, " Hello word ");
485: assertEquals(13, content.length());
486: content.insertString(0, " Hello word ");
487: assertEquals(25, content.length());
488: content.remove(0, 0);
489: assertEquals(25, content.length());
490: content.remove(0, 2);
491: assertEquals(23, content.length());
492: content.remove(1, 3);
493: assertEquals(20, content.length());
494: content.remove(content.length() - 2, 1);
495: assertEquals(19, content.length());
496: content = new StringContent(20);
497: assertEquals(1, content.length());
498: content.insertString(0, " Hello word ");
499: assertEquals(13, content.length());
500: content.insertString(0, " Hello word ");
501: assertEquals(25, content.length());
502: content.remove(0, 0);
503: assertEquals(25, content.length());
504: content.remove(0, 2);
505: assertEquals(23, content.length());
506: content.remove(1, 3);
507: assertEquals(20, content.length());
508: content.remove(content.length() - 2, 1);
509: assertEquals(19, content.length());
510: }
511:
512: public void testInnerContentSize() throws BadLocationException {
513: content = new StringContent(30);
514: insertStringManyTimes("a", 160, content);
515: content.getChars(0, content.length(), text);
516: assertEquals(160, text.count);
517: assertEquals(30 * 8, text.array.length);
518: content = new StringContent();
519: insertStringManyTimes("a", 159, content);
520: content.getChars(0, content.length(), text);
521: assertEquals(159, text.count);
522: assertEquals(10 * 16, text.array.length);
523: content.insertString(0, "i");
524: content.getChars(0, content.length(), text);
525: assertEquals(160, text.count);
526: assertEquals(10 * 16 * 2, text.array.length);
527: // If after insert operation new content length
528: // exceeds current content size, content size
529: // will increaze:
530: content = new StringContent();
531: content.insertString(0, createString(100));
532: content.getChars(0, content.length(), text);
533: assertEquals(100, text.count);
534: if (isHarmony()) {
535: assertEquals(200, text.array.length);
536: } else {
537: assertEquals(100, text.array.length);
538: }
539: insertStringManyTimes("a", 11, content);
540: content.getChars(0, content.length(), text);
541: assertEquals(110, text.count);
542: assertEquals(200, text.array.length);
543: // Rule1
544: //
545: // If after insert operation new content length
546: // doesn't exceed content size, then content size
547: // wont be enlarged.
548: content = new StringContent(101);
549: content.insertString(0, createString(99));
550: content.getChars(0, content.length(), text);
551: assertEquals(99, text.count);
552: assertEquals(101, text.array.length);
553: content.insertString(0, "i");
554: content.getChars(0, content.length(), text);
555: assertEquals(100, text.count);
556: assertEquals(101, text.array.length);
557: // This test shows that Rule1 is "initial length free"
558: content = new StringContent(101);
559: content.insertString(0, createString(100));
560: content.getChars(0, content.length(), text);
561: assertEquals(100, text.count);
562: assertEquals(101, text.array.length);
563: content.insertString(0, "i");
564: content.getChars(0, content.length(), text);
565: assertEquals(101, text.count);
566: assertEquals(202, text.array.length);
567: content.insertString(0, createString(103));
568: content.getChars(0, content.length(), text);
569: assertEquals(203, text.count);
570: assertEquals(404, text.array.length);
571: content.insertString(0, createString(301));
572: content.getChars(0, content.length(), text);
573: assertEquals(503, text.count);
574: assertEquals(808, text.array.length);
575: // Rule2
576: //
577: // If after insert operation new content length
578: // exceeds content size more than twice, new
579: content = new StringContent(251);
580: content.insertString(0, createString(503));
581: content.getChars(0, content.length(), text);
582: assertEquals(503, text.count);
583: if (isHarmony()) {
584: // newSize = (length()+insertedStringLength) * 2
585: assertEquals(1006, text.array.length);
586: } else {
587: // content size will be changed to new content length
588: assertEquals(503, text.array.length);
589: }
590: //Rule3
591: //
592: //If after insert operation new content length
593: //exceeds content size less than twice, new
594: //content size will be changed to (content size) * 2
595: content = new StringContent(252);
596: content.insertString(0, createString(503));
597: content.getChars(0, content.length(), text);
598: assertEquals(503, text.count);
599: assertEquals(504, text.array.length);
600: }
601:
602: private void insertStringManyTimes(String str, int ntimes,
603: StringContent content) throws BadLocationException {
604: for (int i = 1; i < ntimes; i++) {
605: content.insertString(0, str);
606: }
607: }
608:
609: private String createString(final int size) {
610: StringBuffer result = new StringBuffer();
611: for (int i = 1; i < size; i++) {
612: result.append('a');
613: }
614: return result.toString();
615: }
616: }
|