blob: 88e258587554aa064475c3a8a00cf0a724cf798c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.editor.lib2.view;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JEditorPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import junit.framework.TestCase;
import org.netbeans.junit.Filter;
import org.netbeans.junit.NbTestCase;
import org.netbeans.spi.editor.highlighting.support.PositionsBag;
import static org.netbeans.modules.editor.lib2.view.ViewUpdatesTesting.HI_VIEW;
import static org.netbeans.modules.editor.lib2.view.ViewUpdatesTesting.TAB_VIEW;
import static org.netbeans.modules.editor.lib2.view.ViewUpdatesTesting.NL_VIEW;
import static org.netbeans.modules.editor.lib2.view.ViewUpdatesTesting.P_VIEW;
import static org.netbeans.modules.editor.lib2.view.ViewUpdatesTesting.VIEW_BUILDER_TEST_VALUE_NAMES;
import org.netbeans.spi.editor.highlighting.support.OffsetsBag;
/**
*
* @author mmetelka
*/
public class ViewUpdatesExtraFactoryTest extends NbTestCase {
public ViewUpdatesExtraFactoryTest(String testName) {
super(testName);
List<String> includes = new ArrayList<String>();
// includes.add("testExtraHighlightSpansNewline");
// filterTests(includes);
}
private void filterTests(List<String> includeTestNames) {
List<Filter.IncludeExclude> includeTests = new ArrayList<Filter.IncludeExclude>();
for (String testName : includeTestNames) {
includeTests.add(new Filter.IncludeExclude(testName, ""));
}
Filter filter = new Filter();
filter.setIncludes(includeTests.toArray(new Filter.IncludeExclude[includeTests.size()]));
setFilter(filter);
}
@Override
protected void setUp() throws Exception {
super.setUp();
ViewUpdatesTesting.registerTestFactory();
ViewUpdatesTesting.setTestValuesNames(VIEW_BUILDER_TEST_VALUE_NAMES);
}
@Override
protected int timeOut() {
return super.timeOut();
// return 10000000;
}
@Override
protected Level logLevel() {
return Level.INFO; // null;
// return Level.FINEST;
}
private static void loggingOn() {
// FINEST throws ISE for integrity error in EditorView
Logger.getLogger("org.netbeans.modules.editor.lib2.view.EditorView").setLevel(Level.FINEST);
ViewHierarchyImpl.CHECK_LOG.setLevel(Level.FINEST);
// Logger.getLogger("org.netbeans.modules.editor.lib2.view.ViewBuilder").setLevel(LOG_LEVEL);
// Logger.getLogger("org.netbeans.modules.editor.lib2.view.ViewUpdates").setLevel(LOG_LEVEL);
// Check gap-storage correctness
// Logger.getLogger("org.netbeans.modules.editor.lib2.view.EditorBoxViewChildren").setLevel(Level.FINE);
}
private static void addHighlight(Document doc, PositionsBag bag, int startOffset, int endOffset, AttributeSet attrs)
throws BadLocationException
{
bag.addHighlight(doc.createPosition(startOffset), doc.createPosition(endOffset), attrs);
}
public void testExtraHighlightSpansNewline() throws Exception {
loggingOn();
ViewUpdatesTesting.setTestValues(ViewUpdatesTesting.NO_OP_TEST_VALUE);
JEditorPane pane = ViewUpdatesTesting.createPane();
Document doc = pane.getDocument();
final DocumentView docView = DocumentView.get(pane);
final PositionsBag highlights = ViewUpdatesTesting.getSingleHighlightingLayer(pane);
int offset;
String text;
int removeLength;
int HIGHLIGHT_COUNT = 30;
// Test at least GAP_STORAGE_THRESHOLD
assert (HIGHLIGHT_COUNT > ViewGapStorage.GAP_STORAGE_THRESHOLD);
StringBuilder sbLine = new StringBuilder(200);
String hlText = "ab";
for (int i = HIGHLIGHT_COUNT; i > 0; i--) {
sbLine.append(hlText);
}
sbLine.append('\n');
int lineLen = sbLine.length();
int LINE_COUNT = 2;
StringBuilder sb = new StringBuilder(400);
for (int i = LINE_COUNT; i > 0; i--) {
sb.append(sbLine);
}
text = sb.toString();
offset = 0;
doc.insertString(offset, text, null);
// Add highlights
final PositionsBag hlts = new PositionsBag(doc);
offset = 0;
for (int i = LINE_COUNT; i > 0; i--) {
for (int j = HIGHLIGHT_COUNT; j > 0; j--) {
addHighlight(doc, hlts, offset, offset + 2, ViewUpdatesTesting.FONT_ATTRS[j % 2]);
offset += hlText.length();
}
assert (text.charAt(offset) == '\n');
offset++; // skip newline
}
doc.render(new Runnable() {
@Override
public void run() {
highlights.setHighlights(hlts); // since non-empty setTestValues() is active no delayed rebuild occurs
}
});
docView.op.viewsRebuildOrMarkInvalid(); // Manually mark affected children as invalid
docView.ensureAllParagraphsChildrenAndLayoutValid();
ViewUpdatesTesting.checkViews(docView, 0, 6,
hlText.length(), HI_VIEW,
hlText.length(), HI_VIEW,
hlText.length(), HI_VIEW
);
// Set a test highlight that spans end of first line. View creation should
// continue to next line (EVFactory.continueCreation() should be called).
TestHighlightsViewFactory testFactory = ViewUpdatesTesting.getTestFactory(pane);
List<TestHighlight> testHlts = ViewUpdatesTesting.getHighlightsCopy(testFactory);
TestHighlight testHlt = TestHighlight.create(
ViewUtils.createPosition(doc, lineLen - 2),
ViewUtils.createPosition(doc, lineLen + 1),
ViewUpdatesTesting.FONT_ATTRS[2]
);
testHlts.add(testHlt);
testFactory.setHighlights(testHlts);
// No firing of change - just change whether infrastructure handles situation well.
// Now perform insert at point where the extra highlight starts.
// Force extra view factory to produce view that spans newline.
offset = testHlt.startOffset(); // one char before newline
text = "x";
// Expect the test factory will get continueCreation() call:
// startOffset: end of produced highlight (that spanned newline); held by position => text length incorporated.
// endOffset: end of second line + inserted text length
testFactory.setContinueCreationRange(testHlt.endOffset() + text.length(), lineLen * 2 + text.length());
ViewUpdatesTesting.setTestValues(
/*rebuildCause*/ ViewBuilder.RebuildCause.MOD_UPDATE,
/*createLocalViews*/ true,
/*startCreationOffset*/ offset - 1,
/*matchOffset*/ offset + 1 +text.length(),
/*endCreationOffset*/ lineLen + text.length(), // includes '\n'
/*bmReuseOffset*/ offset - 1,
/*bmReusePView*/ docView.getParagraphView(0),
/*bmReuseLocalIndex*/ 29,
/*amReuseOffset*/ offset + 2,
/*amReusePIndex*/ 0,
/*amReusePView*/ docView.getParagraphView(0),
/*amReuseLocalIndex*/ 30
);
doc.insertString(offset, text, null);
if (docView.getParagraphView(0).children.gapStorage == null) {
// TestCase.fail("Expecting non-null gapStorage");
}
if (!testFactory.isContinueCreationUnset()) {
// TestCase.fail("Expecting continueCreation() called.");
}
ViewUpdatesTesting.setTestValues();
}
public void testNullChildren() throws Exception {
loggingOn();
ViewUpdatesTesting.setTestValues(ViewUpdatesTesting.NO_OP_TEST_VALUE);
JEditorPane pane = ViewUpdatesTesting.createPane();
Document doc = pane.getDocument();
final DocumentView docView = DocumentView.get(pane);
// Insert twice the length of chars that would be otherwise serviced with local views creation
int insertCount = ViewBuilder.MAX_CHARS_FOR_CREATE_LOCAL_VIEWS;
String insertText = "a\n";
for (int i = 0; i <= insertCount; i++) {
doc.insertString(0, insertText, null);
}
int docLen = doc.getLength();
int lineCount = doc.getDefaultRootElement().getElementCount();
docView.op.releaseChildren(false);
docView.ensureLayoutValidForInitedChildren();
docView.children.ensureParagraphsChildrenAndLayoutValid(docView, 0, lineCount / 2, 0, 0);
int hlStartOffset = docLen * 1 / 5;
int hlStartPIndex = doc.getDefaultRootElement().getElementIndex(hlStartOffset);
int hlEndOffset = hlStartOffset * 2;
int hlEndPIndex = hlStartPIndex * 2;
TestHighlightsViewFactory testFactory = ViewUpdatesTesting.getTestFactory(pane);
List<TestHighlight> testHlts = ViewUpdatesTesting.getHighlightsCopy(testFactory);
TestHighlight testHlt = TestHighlight.create(
ViewUtils.createPosition(doc, hlStartOffset),
ViewUtils.createPosition(doc, hlEndOffset),
ViewUpdatesTesting.FONT_ATTRS[2]
);
testHlts.add(testHlt);
testFactory.setHighlights(testHlts);
testFactory.fireChange(hlStartOffset, hlEndOffset);
docView.op.viewsRebuildOrMarkInvalid(); // Manually mark affected children as invalid
docView.children.ensureParagraphsChildrenAndLayoutValid(docView,
hlStartPIndex, hlEndPIndex, 0, 0);
ViewUpdatesTesting.setTestValues();
}
public void testHighlightBeyondDocEnd() throws Exception {
loggingOn();
ViewUpdatesTesting.setTestValues(ViewUpdatesTesting.NO_OP_TEST_VALUE);
JEditorPane pane = ViewUpdatesTesting.createPane();
Document doc = pane.getDocument();
final DocumentView docView = DocumentView.get(pane);
final OffsetsBag highlights = ViewUpdatesTesting.getSingleHighlightingLayerOffsets(pane);
String text = "abcd\nefgh";
doc.insertString(0, text, null);
highlights.addHighlight(0, 5, ViewUpdatesTesting.FONT_ATTRS[0]);
highlights.addHighlight(7, doc.getLength() + 2, ViewUpdatesTesting.FONT_ATTRS[1]); // Beyond doc's end
docView.op.viewsRebuildOrMarkInvalid(); // Manually mark affected children as invalid
docView.ensureAllParagraphsChildrenAndLayoutValid();
}
public void testCustomHighlightBeyondDocEnd() throws Exception {
loggingOn();
ViewUpdatesTesting.setTestValues(ViewUpdatesTesting.NO_OP_TEST_VALUE);
JEditorPane pane = ViewUpdatesTesting.createPane();
Document doc = pane.getDocument();
final DocumentView docView = DocumentView.get(pane);
final TestOffsetsHighlightsContainer highlights = new TestOffsetsHighlightsContainer();
ViewUpdatesTesting.getSingleHighlightingLayerCustom(pane, highlights);
highlights.setOffsetPairs(new int[] { 0, 5 });
String text = "abcd\nefgh";
doc.insertString(0, text, null);
docView.op.viewsRebuildOrMarkInvalid(); // Manually mark affected children as invalid
docView.ensureAllParagraphsChildrenAndLayoutValid();
highlights.setOffsetPairs(new int[] { 3, 9 });
doc.remove(0, doc.getLength());
}
}