diff options
-rw-r--r-- | org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleDocumentAdapterTests.java | 963 |
1 files changed, 963 insertions, 0 deletions
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleDocumentAdapterTests.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleDocumentAdapterTests.java index 8292afd83..02205f1d6 100644 --- a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleDocumentAdapterTests.java +++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/ConsoleDocumentAdapterTests.java @@ -19,6 +19,11 @@ import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +import org.eclipse.core.runtime.ILogListener; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; import org.eclipse.debug.tests.AbstractDebugTest; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; @@ -30,6 +35,9 @@ import org.eclipse.ui.internal.console.ConsoleDocumentAdapter; /** * Tests {@link ConsoleDocumentAdapter}. + * <p> + * Primary tests fixed width mode and calculation of {@link TextChangingEvent}s. + * </p> */ @SuppressWarnings("restriction") public class ConsoleDocumentAdapterTests extends AbstractDebugTest { @@ -67,6 +75,834 @@ public class ConsoleDocumentAdapterTests extends AbstractDebugTest { } /** + * Test fixed width line wrap. (mostly with changes affecting a single line) + */ + public void testLineWrap() { + final Random rand = new Random(4); + final int wrapWidth = 10; + final IDocumentAdapter docAdapter = new ConsoleDocumentAdapter(wrapWidth); + final ExpectingTextChangeListener eventListener = new ExpectingTextChangeListener(false, docAdapter); + assertEquals("Failed to set width.", wrapWidth, ((ConsoleDocumentAdapter) docAdapter).getWidth()); + docAdapter.setDocument(new Document()); + docAdapter.addTextChangeListener(eventListener); + // repeated add should not result in repeated events + docAdapter.addTextChangeListener(eventListener); + + // initialize document + final String initText = "012345"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.SET)); + docAdapter.setText(initText); + assertNumberOfLines(docAdapter, 1); + assertLine(docAdapter, 0, initText); + checkLineMapping(docAdapter, rand); + + // add text without new line wrap + String addText = "67"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText); + assertNumberOfLines(docAdapter, 1); + assertLine(docAdapter, 0, "01234567"); + checkLineMapping(docAdapter, rand); + + // add text with one new line wrap + addText = "89AB"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText); + assertNumberOfLines(docAdapter, 2); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "AB"); + checkLineMapping(docAdapter, rand); + + // insert text in wrapped line without new line wrap + int offset = 6; + addText = "---"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 1, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 0, addText); + assertNumberOfLines(docAdapter, 2); + assertLine(docAdapter, 0, "012345---6"); + assertLine(docAdapter, 1, "789AB"); + checkLineMapping(docAdapter, rand); + + // remove last insert + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", 3, 0, 1, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 3, ""); + assertNumberOfLines(docAdapter, 2); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "AB"); + checkLineMapping(docAdapter, rand); + + // add text with two new line wrap + addText = "CDEFGHIJabcdefghijKL"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 2)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText); + assertNumberOfLines(docAdapter, 4); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KL"); + checkLineMapping(docAdapter, rand); + + // replace text without new line wrap + String replaceText = "~~~"; + offset = 3; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, replaceText, replaceText.length(), replaceText.length(), 0, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, replaceText.length(), replaceText); + assertNumberOfLines(docAdapter, 4); + assertLine(docAdapter, 0, "012~~~6789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KL"); + checkLineMapping(docAdapter, rand); + + // remove text with one removed line wrap + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", 3, 0, 3, 2)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 3, ""); + assertNumberOfLines(docAdapter, 3); + assertLine(docAdapter, 0, "012" + "6789ABC"); + assertLine(docAdapter, 1, "DEFGHIJabc"); + assertLine(docAdapter, 2, "defghijKL"); + checkLineMapping(docAdapter, rand); + + // insert text with one new line wrap + addText = "345"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 2, 3)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 0, addText); + assertNumberOfLines(docAdapter, 4); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KL"); + checkLineMapping(docAdapter, rand); + + // add text ending at fixed width border + addText = "MNOPQRST"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText); + assertNumberOfLines(docAdapter, 4); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KLMNOPQRST"); + assertEquals("Got wrong line index.", 3, docAdapter.getLineAtOffset(40)); + checkLineMapping(docAdapter, rand); + + // add text starting at fixed width border + addText = "kl"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 0, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText); + assertNumberOfLines(docAdapter, 5); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KLMNOPQRST"); + assertLine(docAdapter, 4, "kl"); + checkLineMapping(docAdapter, rand); + + // insert text starting at fixed width border + addText = ">"; + offset = docAdapter.getCharCount() - 2; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 0, addText); + assertNumberOfLines(docAdapter, 5); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KLMNOPQRST"); + assertLine(docAdapter, 4, ">kl"); + checkLineMapping(docAdapter, rand); + + // delete character at fixed width border + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 1, ""); + assertNumberOfLines(docAdapter, 5); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KLMNOPQRST"); + assertLine(docAdapter, 4, "kl"); + checkLineMapping(docAdapter, rand); + + // add newline to start... new line + addText = "\n"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText); + assertNumberOfLines(docAdapter, 6); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KLMNOPQRST"); + assertLine(docAdapter, 4, "kl"); + assertLine(docAdapter, 5, ""); + assertEquals("Got wrong line.", 4, docAdapter.getLineAtOffset(docAdapter.getCharCount() - 2)); + assertEquals("Got wrong line.", 4, docAdapter.getLineAtOffset(docAdapter.getCharCount() - 1)); + assertEquals("Got wrong line.", 5, docAdapter.getLineAtOffset(docAdapter.getCharCount())); + assertEquals("Get wrong content.", "\n", docAdapter.getTextRange(42, 1)); + checkLineMapping(docAdapter, rand); + + // add text ending at fixed width border + addText = "UVWXYZ.,:;"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText); + assertNumberOfLines(docAdapter, 6); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KLMNOPQRST"); + assertLine(docAdapter, 4, "kl"); + assertLine(docAdapter, 5, "UVWXYZ.,:;"); + assertEquals("Got wrong line.", 5, docAdapter.getLineAtOffset(docAdapter.getCharCount())); + assertEquals("Get wrong content.", "l\nU", docAdapter.getTextRange(41, 3)); + checkLineMapping(docAdapter, rand); + + // remove text without line wrap change + offset = docAdapter.getOffsetAtLine(docAdapter.getLineCount() - 1) + 2; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", 4, 0, 0, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 4, ""); + assertNumberOfLines(docAdapter, 6); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KLMNOPQRST"); + assertLine(docAdapter, 4, "kl"); + assertLine(docAdapter, 5, "UV" + ".,:;"); + checkLineMapping(docAdapter, rand); + + // replace and insert text and end at fixed width border + replaceText = "WXYZ.,:;"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, replaceText, 4, replaceText.length(), 0, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 4, replaceText); + assertNumberOfLines(docAdapter, 6); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KLMNOPQRST"); + assertLine(docAdapter, 4, "kl"); + assertLine(docAdapter, 5, "UVWXYZ.,:;"); + assertEquals("Got wrong line.", 5, docAdapter.getLineAtOffset(docAdapter.getCharCount())); + checkLineMapping(docAdapter, rand); + + // replace text without length change + offset = docAdapter.getCharCount() - 3; + replaceText = "~~~"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, replaceText, replaceText.length(), replaceText.length(), 0, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, replaceText.length(), replaceText); + assertNumberOfLines(docAdapter, 6); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KLMNOPQRST"); + assertLine(docAdapter, 4, "kl"); + assertLine(docAdapter, 5, "UVWXYZ.~~~"); + assertEquals("Got wrong line.", 5, docAdapter.getLineAtOffset(docAdapter.getCharCount())); + checkLineMapping(docAdapter, rand); + + // insert text with one new line wrap + addText = ",:;"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 0, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 0, addText); + assertNumberOfLines(docAdapter, 7); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KLMNOPQRST"); + assertLine(docAdapter, 4, "kl"); + assertLine(docAdapter, 5, "UVWXYZ.,:;"); + assertLine(docAdapter, 6, "~~~"); + checkLineMapping(docAdapter, rand); + + // manipulate text so both document lines end at wrap border + addText = "mnopqrst"; + offset = 42; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 0, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 0, addText); + replaceText = "uvwxyz_-=|"; + offset = docAdapter.getCharCount() - 3; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 3, replaceText); + assertNumberOfLines(docAdapter, 7); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abcdefghij"); + assertLine(docAdapter, 3, "KLMNOPQRST"); + assertLine(docAdapter, 4, "klmnopqrst"); // <-- real line delimiter here + assertLine(docAdapter, 5, "UVWXYZ.,:;"); + assertLine(docAdapter, 6, "uvwxyz_-=|"); + assertEquals("Got wrong line.", 4, docAdapter.getLineAtOffset(49)); + assertEquals("Got wrong line.", 4, docAdapter.getLineAtOffset(50)); + assertEquals("Got wrong line.", 5, docAdapter.getLineAtOffset(51)); + assertEquals("Got wrong line.", 6, docAdapter.getLineAtOffset(docAdapter.getCharCount())); + checkLineMapping(docAdapter, rand); + + // remove last wrapped line + offset = docAdapter.getOffsetAtLine(docAdapter.getLineCount() - 1); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 10, ""); + assertNumberOfLines(docAdapter, 6); + checkLineMapping(docAdapter, rand); + + // replace text ending at wrap border without new line wrap + replaceText = "~~~"; + offset = 7; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, replaceText, replaceText.length(), replaceText.length(), 0, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, replaceText.length(), replaceText); + assertNumberOfLines(docAdapter, 6); + assertLine(docAdapter, 0, "0123456~~~"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + checkLineMapping(docAdapter, rand); + + // remove 5th line including it's real line delimiter + offset = docAdapter.getOffsetAtLine(5 - 1); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, null, null)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 11, ""); + assertNumberOfLines(docAdapter, 5); + assertLine(docAdapter, 3, "KLMNOPQRST"); + assertLine(docAdapter, 4, "UVWXYZ.,:;"); + checkLineMapping(docAdapter, rand); + + // remove text ending at wrap border + int remove = 3; + offset = 7; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 4, 4)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, remove, ""); + assertNumberOfLines(docAdapter, 5); + assertLine(docAdapter, 0, "0123456ABC"); + assertLine(docAdapter, 1, "DEFGHIJabc"); + assertLine(docAdapter, 2, "defghijKLM"); + assertLine(docAdapter, 3, "NOPQRSTUVW"); + assertLine(docAdapter, 4, "XYZ.,:;"); + checkLineMapping(docAdapter, rand); + + assertFalse("Some expected change events were not received.", eventListener.hasPendingExpections()); + docAdapter.removeTextChangeListener(eventListener); + clearDocument(docAdapter); + } + + /** + * Test inserting text containing line delimiters. + */ + public void testMultilineInserts() { + final Random rand = new Random(4); + final int wrapWidth = 10; + final IDocumentAdapter docAdapter = new ConsoleDocumentAdapter(wrapWidth); + final ExpectingTextChangeListener eventListener = new ExpectingTextChangeListener(false, docAdapter); + assertEquals("Failed to set width.", wrapWidth, ((ConsoleDocumentAdapter) docAdapter).getWidth()); + docAdapter.setDocument(new Document()); + docAdapter.addTextChangeListener(eventListener); + + // add 4 new document lines with 1 line wrapped + String addText = "012345\nABCDEFGHIJa\r\n\nklmnopqrst\r\nuv"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, 0, addText, 0, addText.length(), 0, 5)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(0, 0, addText); + assertNumberOfLines(docAdapter, 6); + assertLine(docAdapter, 0, "012345"); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "a"); + assertLine(docAdapter, 3, ""); + assertLine(docAdapter, 4, "klmnopqrst"); + assertLine(docAdapter, 5, "uv"); + checkLineMapping(docAdapter, rand); + + // insert newline at begin of line + addText = "\n"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, 0, addText, 0, addText.length(), 0, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(0, 0, addText); + assertNumberOfLines(docAdapter, 7); + assertLine(docAdapter, 0, ""); + assertLine(docAdapter, 1, "012345"); + checkLineMapping(docAdapter, rand); + + // insert text + newline at begin of line + addText = "9876543210?\n"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, 0, addText, 0, addText.length(), 0, 2)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(0, 0, addText); + assertNumberOfLines(docAdapter, 9); + assertLine(docAdapter, 0, "9876543210"); + assertLine(docAdapter, 1, "?"); + assertLine(docAdapter, 2, ""); + checkLineMapping(docAdapter, rand); + + // insert newline + text at begin of line + addText = "\r\nfoo"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, 0, addText, 0, addText.length(), 1, 2)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(0, 0, addText); + assertNumberOfLines(docAdapter, 10); + assertLine(docAdapter, 0, ""); + assertLine(docAdapter, 1, "foo9876543"); + assertLine(docAdapter, 2, "210?"); + assertLine(docAdapter, 3, ""); + checkLineMapping(docAdapter, rand); + + // insert text + newline + text at begin of line + addText = ".,:;\r\nbar"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, 0, addText, 0, addText.length(), 0, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(0, 0, addText); + assertNumberOfLines(docAdapter, 11); + assertLine(docAdapter, 0, ".,:;"); + assertLine(docAdapter, 1, "bar"); + assertLine(docAdapter, 2, "foo9876543"); + checkLineMapping(docAdapter, rand); + + // insert 2 newline at end of line + addText = "\r\n\n"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 2)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText); + assertNumberOfLines(docAdapter, 13); + assertLine(docAdapter, 10, "uv"); + assertLine(docAdapter, 11, ""); + assertLine(docAdapter, 12, ""); + checkLineMapping(docAdapter, rand); + + // insert text + 2 newline at end of line (one line wrapping) + addText = "BCDEFGHIJKbc\n\n"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 3)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText); + assertNumberOfLines(docAdapter, 16); + assertLine(docAdapter, 12, "BCDEFGHIJK"); + assertLine(docAdapter, 13, "bc"); + assertLine(docAdapter, 14, ""); + assertLine(docAdapter, 15, ""); + checkLineMapping(docAdapter, rand); + + // insert 2 newline + text at end of line + addText = "\r\nLMNOPQR\nlmnopqrst"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 2)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText); + assertNumberOfLines(docAdapter, 18); + assertLine(docAdapter, 15, ""); + assertLine(docAdapter, 16, "LMNOPQR"); + assertLine(docAdapter, 17, "lmnopqrst"); + checkLineMapping(docAdapter, rand); + + // insert text + 2 newline + text at end of line (+one line wrapping) + addText = "uVW\nvwxy\r\n1357902468"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, docAdapter.getCharCount(), addText, 0, addText.length(), 0, 3)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, addText); + assertNumberOfLines(docAdapter, 21); + assertLine(docAdapter, 17, "lmnopqrstu"); + assertLine(docAdapter, 18, "VW"); + assertLine(docAdapter, 19, "vwxy"); + assertLine(docAdapter, 20, "1357902468"); + checkLineMapping(docAdapter, rand); + + // insert newline inside (wrapped) line + int offset = docAdapter.getOffsetAtLine(17) + 8; + addText = "\n"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 1, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 0, addText); + assertNumberOfLines(docAdapter, 21); + assertLine(docAdapter, 17, "lmnopqrs"); + assertLine(docAdapter, 18, "tuVW"); + assertLine(docAdapter, 19, "vwxy"); + checkLineMapping(docAdapter, rand); + + // insert newline + text + newline in existing line + offset = docAdapter.getOffsetAtLine(19) + 2; + addText = "\n[()]\r\n"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 0, 2)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 0, addText); + assertNumberOfLines(docAdapter, 23); + assertLine(docAdapter, 19, "vw"); + assertLine(docAdapter, 20, "[()]"); + assertLine(docAdapter, 21, "xy"); + checkLineMapping(docAdapter, rand); + + // insert newline + long text + newline in existing line + offset = docAdapter.getOffsetAtLine(20); + addText = "\r\nCDEFGHIJKLcdefghijklMNOPQR\n"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 0, 4)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 0, addText); + assertNumberOfLines(docAdapter, 27); + assertLine(docAdapter, 20, ""); + assertLine(docAdapter, 21, "CDEFGHIJKL"); + assertLine(docAdapter, 22, "cdefghijkl"); + assertLine(docAdapter, 23, "MNOPQR"); + assertLine(docAdapter, 24, "[()]"); + checkLineMapping(docAdapter, rand); + + // insert newline inside (wrapped) line + offset = docAdapter.getOffsetAtLine(21) + 9; + addText = "\n"; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, 0, addText.length(), 2, 2)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, 0, addText); + assertNumberOfLines(docAdapter, 27); + assertLine(docAdapter, 21, "CDEFGHIJK"); + assertLine(docAdapter, 22, "Lcdefghijk"); + assertLine(docAdapter, 23, "lMNOPQR"); + checkLineMapping(docAdapter, rand); + + assertFalse("Some expected change events were not received.", eventListener.hasPendingExpections()); + docAdapter.removeTextChangeListener(eventListener); + clearDocument(docAdapter); + } + + /** + * Test text remove affecting than one line. + */ + public void testMultilineRemove() { + final Random rand = new Random(4); + final int wrapWidth = 10; + final ExpectingTextChangeListener eventListener = new ExpectingTextChangeListener(true, null); + final IDocumentAdapter docAdapter = new ConsoleDocumentAdapter(wrapWidth); + assertEquals("Failed to set width.", wrapWidth, ((ConsoleDocumentAdapter) docAdapter).getWidth()); + docAdapter.setDocument(new Document()); + docAdapter.addTextChangeListener(eventListener); + + // prepare one wrapped line + clearDocument(docAdapter); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "0123456789"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "ABCDE"); + // remove over wrap border but wrap remains + int offset = 8; + int remove = 4; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 1, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, remove, ""); + assertNumberOfLines(docAdapter, 2); + assertLine(docAdapter, 0, "01234567CD"); + assertLine(docAdapter, 1, "E"); + checkLineMapping(docAdapter, rand); + + // perform empty change event + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, 0, "", 0, 0, 0, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(0, 0, ""); + assertFalse("Some expected change events were not received.", eventListener.hasPendingExpections()); + checkLineMapping(docAdapter, rand); + + // remove over wrap border (removes wrap) + offset = 8; + remove = 3; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 1, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, remove, ""); + assertNumberOfLines(docAdapter, 1); + assertLine(docAdapter, 0, "01234567"); + checkLineMapping(docAdapter, rand); + + // prepare one double wrapped line + clearDocument(docAdapter); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "0123456789"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "ABCDEFGHIJ"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "abcde"); + // remove over two wrap border + offset = 8; + remove = 14; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 2, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, remove, ""); + assertNumberOfLines(docAdapter, 2); + assertLine(docAdapter, 0, "01234567cd"); + assertLine(docAdapter, 1, "e"); + checkLineMapping(docAdapter, rand); + + // remove at fixed width border + offset = 10; + remove = 1; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, remove, ""); + assertNumberOfLines(docAdapter, 1); + assertLine(docAdapter, 0, "01234567cd"); + checkLineMapping(docAdapter, rand); + + // prepare two unwrapped lines + clearDocument(docAdapter); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "01234567\n"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "ABCDEF"); + // remove line delimiter (produces wrapped line) + offset = 8; + remove = 1; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 1, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, remove, ""); + assertNumberOfLines(docAdapter, 2); + assertLine(docAdapter, 0, "01234567AB"); + assertLine(docAdapter, 1, "CDEF"); + checkLineMapping(docAdapter, rand); + + // prepare some more lines + clearDocument(docAdapter); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "01234567\n"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "ABCDEFGHIJ"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "abcdefghij"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "KLMN\r\n"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "klmno\n"); + assertLine(docAdapter, 5, ""); + // remove multiple lines + offset = 5; + remove = 36; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 5, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, remove, ""); + assertNumberOfLines(docAdapter, 1); + assertLine(docAdapter, 0, "01234"); + checkLineMapping(docAdapter, rand); + + // prepare more lines + clearDocument(docAdapter); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "01234567\n"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "\n"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "\r\n"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "\n"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, docAdapter.getLineDelimiter()); + assertNumberOfLines(docAdapter, 6); + // remove empty lines + // (and do not start in first line like most tests before) + offset = 10; + remove = 3; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, "", remove, 0, 2, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, remove, ""); + assertNumberOfLines(docAdapter, 4); + checkLineMapping(docAdapter, rand); + + assertFalse("Some expected change events were not received.", eventListener.hasPendingExpections()); + } + + /** + * Test text change affecting and inserting more than one line. + */ + public void testMultilineReplace() { + final Random rand = new Random(4); + final int wrapWidth = 10; + final ExpectingTextChangeListener eventListener = new ExpectingTextChangeListener(true, null); + final IDocumentAdapter docAdapter = new ConsoleDocumentAdapter(wrapWidth); + assertEquals("Failed to set width.", wrapWidth, ((ConsoleDocumentAdapter) docAdapter).getWidth()); + docAdapter.setDocument(new Document()); + docAdapter.addTextChangeListener(eventListener); + + docAdapter.setText("0123~~~AB"); + + // remove in single line and insert newline + String addText = "\n"; + int offset = 4; + int length = 3; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, length, addText.length(), 0, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, length, addText); + assertNumberOfLines(docAdapter, 2); + assertLine(docAdapter, 0, "0123"); // \n + assertLine(docAdapter, 1, "AB"); + checkLineMapping(docAdapter, rand); + + // replace newline with more text and a new newline + addText = "456789abc\r\n+"; + length = 2; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, length, addText.length(), 1, 2)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, length, addText); + assertNumberOfLines(docAdapter, 3); + assertLine(docAdapter, 0, "0123456789"); + assertLine(docAdapter, 1, "abc"); // \r\n + assertLine(docAdapter, 2, "+B"); + checkLineMapping(docAdapter, rand); + + // remove and insert newline + addText = "<->\nABCDEFGHIJabc\n#"; + length = 12; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, length, addText.length(), 2, 3)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, length, addText); + assertNumberOfLines(docAdapter, 4); + assertLine(docAdapter, 0, "0123<->"); // \n + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "abc"); // \n + assertLine(docAdapter, 3, "#B"); + checkLineMapping(docAdapter, rand); + + // insert newline and replace wrap + addText = "\n>=<"; + offset = 18; + length = 3; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, length, addText); + assertNumberOfLines(docAdapter, 4); + assertLine(docAdapter, 0, "0123<->"); // \n + assertLine(docAdapter, 1, "ABCDEFGHIJ"); // \n + assertLine(docAdapter, 2, ">=<"); // \n + assertLine(docAdapter, 3, "#B"); + checkLineMapping(docAdapter, rand); + + addText = "*+"; + offset = docAdapter.getCharCount() - 2; + length = 1; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, offset, addText, length, addText.length(), 0, 0)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, length, addText); + assertNumberOfLines(docAdapter, 4); + assertLine(docAdapter, 2, ">=<"); // \n + assertLine(docAdapter, 3, "*+B"); + checkLineMapping(docAdapter, rand); + + docAdapter.setText(""); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "0123456789"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "ABCDEFGHIJ"); + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, "a"); + addText = "$b"; + offset = docAdapter.getCharCount() - 1; + length = 1; + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGING, null, null, null, null, 1, 1)); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.CHANGED)); + docAdapter.replaceTextRange(offset, length, addText); + assertNumberOfLines(docAdapter, 3); + assertLine(docAdapter, 1, "ABCDEFGHIJ"); + assertLine(docAdapter, 2, "$b"); + checkLineMapping(docAdapter, rand); + + assertFalse("Some expected change events were not received.", eventListener.hasPendingExpections()); + } + + /** + * Test line wrapping is correctly updated if fixed width changed. + */ + public void testSetWidth() { + final Random rand = new Random(7); + final ConsoleDocumentAdapter docAdapter = new ConsoleDocumentAdapter(-1); + docAdapter.setDocument(new Document()); + + final String line0_0 = "#123456789"; + final String line0_1 = "ABCDEF"; + final String line0 = line0_0 + line0_1; + final String line1 = ""; + final String line2 = "abcd"; + final String text = line0 + "\n" + line1 + "\r\n" + line2; + docAdapter.setText(text); + assertEquals("Get text range failed.", "#", docAdapter.getTextRange(0, 1)); + + // check with initial disabled fixed width mode + assertLine(docAdapter, 0, line0); + assertLine(docAdapter, 1, line1); + assertLine(docAdapter, 2, line2); + assertEquals("Adapter content length wrong.", text.length(), docAdapter.getCharCount()); + checkLineMapping(docAdapter, rand); + + // test with enabled fixed width mode + docAdapter.setWidth(10); + docAdapter.setWidth(10); // intentional double set + assertLine(docAdapter, 0, line0_0); + assertLine(docAdapter, 1, line0_1); + assertLine(docAdapter, 2, line1); + assertLine(docAdapter, 3, line2); + assertEquals("Adapter content length wrong.", text.length(), docAdapter.getCharCount()); + checkLineMapping(docAdapter, rand); + + // test with disabled fixed width mode after it was enabled + docAdapter.setWidth(-1); + assertLine(docAdapter, 0, line0); + assertLine(docAdapter, 1, line1); + assertLine(docAdapter, 2, line2); + assertEquals("Adapter content length wrong.", text.length(), docAdapter.getCharCount()); + checkLineMapping(docAdapter, rand); + + // test with fixed width mode but no virtual wrappings + docAdapter.setWidth(80); + assertLine(docAdapter, 0, line0); + assertLine(docAdapter, 1, line1); + assertLine(docAdapter, 2, line2); + assertEquals("Adapter content length wrong.", text.length(), docAdapter.getCharCount()); + checkLineMapping(docAdapter, rand); + + // add a listener for the next width change + final ExpectingTextChangeListener eventListener = new ExpectingTextChangeListener(false, docAdapter); + docAdapter.addTextChangeListener(eventListener); + eventListener.addExpectation(new TextEventExpectation(TextChangeEventType.SET)); + + // test extreme small console + docAdapter.setWidth(1); + int expectedLines = Math.max(line0.length(), 1); + expectedLines += Math.max(line1.length(), 1); + expectedLines += Math.max(line2.length(), 1); + assertNumberOfLines(docAdapter, expectedLines); + checkLineMapping(docAdapter, rand); + assertFalse("Some expected change events were not received.", eventListener.hasPendingExpections()); + } + + /** + * Some test cases derived from JavaDoc examples of {@link IDocumentAdapter} + * (and its super interfaces). + */ + public void testInterfaceContract() { + final ConsoleDocumentAdapter docAdapter = new ConsoleDocumentAdapter(-1); + docAdapter.setDocument(new Document()); + assertNotNull("Adapter has no legal line delimiter.", docAdapter.getLineDelimiter()); + + for (int width : new int[] { -1, 80 }) { + docAdapter.setWidth(width); + + // test against documentation of + // IDocumentAdapter#getLineAtOffset(int) + docAdapter.setText("\r\n\r\n"); + checkLineMapping(docAdapter, null); + assertEquals("Wrong line for offset.", 0, docAdapter.getLineAtOffset(0)); + assertEquals("Wrong line for offset.", 0, docAdapter.getLineAtOffset(1)); + assertEquals("Wrong line for offset.", 1, docAdapter.getLineAtOffset(2)); + assertEquals("Wrong line for offset.", 1, docAdapter.getLineAtOffset(3)); + assertEquals("Wrong line for offset.", 2, docAdapter.getLineAtOffset(4)); + assertEquals("Wrong line for offset.", docAdapter.getLineCount() - 1, docAdapter.getLineAtOffset(docAdapter.getCharCount())); + + // test against documentation of IDocumentAdapter#getLineCount() + docAdapter.setText(null); + assertNumberOfLines(docAdapter, 1); + docAdapter.setText(""); + assertNumberOfLines(docAdapter, 1); + docAdapter.setText("a\n"); + assertNumberOfLines(docAdapter, 2); + docAdapter.setText("\n\n"); + assertNumberOfLines(docAdapter, 3); + + // test against documentation of + // IDocumentAdapter#getOffsetAtLine(int) + docAdapter.setText("\r\ntest\r\n"); + checkLineMapping(docAdapter, null); + assertEquals("Wrong offset for line.", 0, docAdapter.getOffsetAtLine(0)); + assertEquals("Wrong offset for line.", 2, docAdapter.getOffsetAtLine(1)); + assertEquals("Wrong offset for line.", 8, docAdapter.getOffsetAtLine(2)); + docAdapter.setText(""); + assertEquals("Wrong offset for line.", 0, docAdapter.getOffsetAtLine(0)); + } + } + + /** * Test * {@link IDocumentAdapter#setDocument(org.eclipse.jface.text.IDocument)} * and ensure old document is indeed disconnected and not notified anymore. @@ -91,6 +927,118 @@ public class ConsoleDocumentAdapterTests extends AbstractDebugTest { docAdapter.setDocument(null); } + /** + * Test if invalid arguments produces error log messages. + */ + public void _testInvalidInvocations() { + final AtomicInteger expectedErrors = new AtomicInteger(0); + final ILogListener logListener = new ILogListener() { + @Override + public void logging(IStatus status, String plugin) { + if (status.matches(IStatus.ERROR)) { + expectedErrors.decrementAndGet(); + } + } + }; + try { + Platform.addLogListener(logListener); + + final ConsoleDocumentAdapter docAdapter = new ConsoleDocumentAdapter(-1); + docAdapter.setDocument(null); + docAdapter.setDocument(new Document()); + try { + docAdapter.addTextChangeListener(null); + fail("Exception not thrown."); + } catch (IllegalArgumentException ex) { + // expected behavior + } + try { + docAdapter.removeTextChangeListener(null); + fail("Exception not thrown."); + } catch (IllegalArgumentException ex) { + // expected behavior + } + + for (int width : new int[] { -1, -2, 80 }) { + docAdapter.setWidth(width); + if (width != -2) { + docAdapter.setText("?"); + } else { + // In non fixed mode the documents line tracker is used for + // most queries. Document may use different trackers if test + // is set or replaced. + docAdapter.replaceTextRange(0, docAdapter.getCharCount(), "?"); + } + + expectedErrors.set(3); + docAdapter.getLine(Integer.MIN_VALUE); + docAdapter.getLine(-1); + // getLine(1) should be invalid as well but the current + // implementation uses getLineInformation and ListLineTracker + // returns information for this non existing line and + // TreeLineTracke does so for compatibility reasons + docAdapter.getLine(Integer.MAX_VALUE); + assertEquals("Too much success with width: " + width, 0, expectedErrors.get()); + + expectedErrors.set(4); + docAdapter.getLineAtOffset(Integer.MIN_VALUE); + docAdapter.getLineAtOffset(-1); + docAdapter.getLineAtOffset(1); + docAdapter.getLineAtOffset(2); + docAdapter.getLineAtOffset(Integer.MAX_VALUE); + assertEquals("Too much success with width: " + width, 0, expectedErrors.get()); + + expectedErrors.set(4); + docAdapter.getOffsetAtLine(Integer.MIN_VALUE); + docAdapter.getOffsetAtLine(-1); + docAdapter.getOffsetAtLine(1); + docAdapter.getOffsetAtLine(Integer.MAX_VALUE); + assertEquals("Too much success with width: " + width, 0, expectedErrors.get()); + + expectedErrors.set(6); + docAdapter.getTextRange(-1, 1); + docAdapter.getTextRange(0, -1); + docAdapter.getTextRange(1, -1); + docAdapter.getTextRange(-1, 2); + docAdapter.getTextRange(0, 2); + docAdapter.getTextRange(0, 3); + assertEquals("Too much success with width: " + width, 0, expectedErrors.get()); + + expectedErrors.set(10); + docAdapter.replaceTextRange(2, 0, ""); + docAdapter.replaceTextRange(-1, 0, ""); + docAdapter.replaceTextRange(0, 2, ""); + docAdapter.replaceTextRange(0, -1, ""); + docAdapter.replaceTextRange(1, 1, ""); + docAdapter.replaceTextRange(0, 2, "foo"); + docAdapter.replaceTextRange(0, -1, "foo"); + docAdapter.replaceTextRange(1, 1, "foo"); + docAdapter.replaceTextRange(1, -1, "foo"); + docAdapter.replaceTextRange(2, 0, "foo"); + assertEquals("Too much success with width: " + width, 0, expectedErrors.get()); + } + } finally { + Platform.removeLogListener(logListener); + } + } + + /** + * Test adapter with a larger number of lines. (especially tests array grow) + */ + public void testManyLines() { + final ConsoleDocumentAdapter docAdapter = new ConsoleDocumentAdapter(80); + docAdapter.setDocument(new Document()); + final String lineDelimiter = docAdapter.getLineDelimiter(); + final int n = 6000; + for (int i = 0; i < n; i++) { + docAdapter.replaceTextRange(docAdapter.getCharCount(), 0, lineDelimiter); + } + assertNumberOfLines(docAdapter, n + 1); + docAdapter.setWidth(-1); + assertNumberOfLines(docAdapter, n + 1); + clearDocument(docAdapter); + } + private static void assertContent(IDocumentAdapter docAdapter, String content) { assertEquals("Adapter returned wrong content.", content, docAdapter.getTextRange(0, docAdapter.getCharCount())); } @@ -99,6 +1047,10 @@ public class ConsoleDocumentAdapterTests extends AbstractDebugTest { assertEquals("Adapter has wrong line count.", expectedLines, docAdapter.getLineCount()); } + private static void assertLine(IDocumentAdapter docAdapter, int lineIndex, String expectedContent) { + assertEquals("Adapter returned wrong content for line " + lineIndex + ".", expectedContent, docAdapter.getLine(lineIndex)); + } + /** * Goes through every line in adapted document and checks if value of * {@link IDocumentAdapter#getOffsetAtLine(int)} for a line returns the same @@ -134,6 +1086,13 @@ public class ConsoleDocumentAdapterTests extends AbstractDebugTest { } } + private static void clearDocument(IDocumentAdapter docAdapter) { + docAdapter.setText(""); + assertEquals("Document not cleared.", 0, docAdapter.getCharCount()); + assertNumberOfLines(docAdapter, 1); + assertLine(docAdapter, 0, ""); + } + private static class TextEventExpectation { // common attributes /** Expected text change event type. */ @@ -280,6 +1239,10 @@ public class ConsoleDocumentAdapterTests extends AbstractDebugTest { checkCommon(TextChangeEventType.SET); } + public boolean hasPendingExpections() { + return !expectations.isEmpty(); + } + private TextEventExpectation checkCommon(TextChangeEventType eventType) { final TextEventExpectation expectation = expectations.poll(); if (expectation == null && allowUnexpectedEvents) { |