2 * Copyright 2000-2014 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.openapi.editor.richcopy;
18 import com.intellij.openapi.application.ApplicationManager;
19 import com.intellij.openapi.editor.Editor;
20 import com.intellij.openapi.editor.LogicalPosition;
21 import com.intellij.openapi.editor.SelectionModel;
22 import com.intellij.openapi.editor.ex.EditorEx;
23 import com.intellij.openapi.editor.impl.DocumentImpl;
24 import com.intellij.openapi.editor.richcopy.model.ColorRegistry;
25 import com.intellij.openapi.editor.richcopy.model.MarkupHandler;
26 import com.intellij.openapi.editor.richcopy.model.SyntaxInfo;
27 import com.intellij.openapi.util.text.StringUtil;
28 import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
29 import com.intellij.ui.JBColor;
30 import junit.framework.TestCase;
33 * @author Denis Zhdanov
34 * @since 3/27/13 11:11 AM
36 public class SyntaxInfoConstructionTest extends LightPlatformCodeInsightFixtureTestCase {
37 public void testBlockSelection() {
41 "public class TestClass {\n" +
45 " public int getField() {\n" +
51 int blockSelectionStartOffset = text.indexOf("public int");
52 Editor editor = myFixture.getEditor();
53 LogicalPosition blockSelectionStartPosition = editor.offsetToLogicalPosition(blockSelectionStartOffset);
54 LogicalPosition blockSelectionEndPosition = new LogicalPosition(
55 blockSelectionStartPosition.line + 2,
56 editor.offsetToLogicalPosition(text.indexOf('{', blockSelectionStartOffset)).column + 1);
57 editor.getSelectionModel().setBlockSelection(blockSelectionStartPosition, blockSelectionEndPosition);
59 verifySyntaxInfo("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=public int \n" +
60 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=getField() {\n" +
64 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=return \n" +
65 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
66 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
72 public void testColumnModeBlockSelection() {
76 "public class TestClass {\n" +
80 " public int getField() {\n" +
86 int blockSelectionStartOffset = text.indexOf("public int");
87 Editor editor = myFixture.getEditor();
88 ((EditorEx) editor).setColumnMode(true);
89 LogicalPosition blockSelectionStartPosition = editor.offsetToLogicalPosition(blockSelectionStartOffset);
90 LogicalPosition blockSelectionEndPosition = new LogicalPosition(
91 blockSelectionStartPosition.line + 2,
92 editor.offsetToLogicalPosition(text.indexOf('{', blockSelectionStartOffset)).column + 1);
93 editor.getSelectionModel().setBlockSelection(blockSelectionStartPosition, blockSelectionEndPosition);
95 verifySyntaxInfo("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=public int \n" +
96 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=getField() {\n" +
100 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=return \n" +
101 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
102 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
108 public void testColumnModeBlockSelectionWithGaps() {
110 "public class TestClass {\n" +
114 " int otherField;\n" +
118 int blockSelectionStartOffset = text.indexOf("int");
119 Editor editor = myFixture.getEditor();
120 ((EditorEx) editor).setColumnMode(true);
121 LogicalPosition blockSelectionStartPosition = editor.offsetToLogicalPosition(blockSelectionStartOffset);
122 LogicalPosition blockSelectionEndPosition = new LogicalPosition(blockSelectionStartPosition.line + 2, blockSelectionStartPosition.column + 16);
123 editor.getSelectionModel().setBlockSelection(blockSelectionStartPosition, blockSelectionEndPosition);
125 verifySyntaxInfo("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=int \n" +
126 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
127 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
132 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=int \n" +
133 "foreground=java.awt.Color[r=102,g=14,b=122],text=otherField\n" +
134 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n");
137 public void testRegularSelection() {
138 // We want to exclude unnecessary indents from the pasted results.
142 "public class TestClass {\n" +
146 " public int getField() {\n" +
152 int selectionStart = text.indexOf("public int");
153 int selectionEnd = text.indexOf('}', selectionStart) + 1;
154 SelectionModel selectionModel = myFixture.getEditor().getSelectionModel();
155 selectionModel.setSelection(selectionStart, selectionEnd);
157 String expected = "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=public int \n" +
158 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=getField() {\n" +
161 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=return \n" +
162 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
163 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
167 TestCase.assertEquals(expected, getSyntaxInfo());
169 selectionModel.setSelection(selectionStart - 2, selectionEnd);
170 TestCase.assertEquals(expected, getSyntaxInfo());
172 selectionModel.setSelection(selectionStart - 4, selectionEnd);
173 TestCase.assertEquals(expected, getSyntaxInfo());
176 public void testIncorrectFirstLineCalculationOffset() {
177 init("\"tr\" #> <selection>template.statusList.sortBy</selection>(_.index).map(fromStatus =>");
179 verifySyntaxInfo("fontStyle=0,text=template.statusList.sortBy\n");
182 public void testJavadoc() {
186 "import java.io.Serializable;\n" +
189 " * Code in <code>here</code>\n" +
190 " * <strong>Hi</strong> man\n" +
192 " </selection>*/\n" +
193 "public interface SampleTest<T> extends Serializable {\n" +
194 " boolean isNotNull();\n" +
198 verifySyntaxInfo("foreground=java.awt.Color[r=128,g=128,b=128],fontStyle=2,text=/**\n" +
200 "text= * Code in \n" +
201 "background=java.awt.Color[r=226,g=255,b=226],text=<code>\n" +
202 "background=java.awt.Color[r=255,g=255,b=255],text=here\n" +
203 "background=java.awt.Color[r=226,g=255,b=226],text=</code>\n" +
204 "background=java.awt.Color[r=255,g=255,b=255],text=\n" +
207 "background=java.awt.Color[r=226,g=255,b=226],text=<strong>\n" +
208 "background=java.awt.Color[r=255,g=255,b=255],text=Hi\n" +
209 "background=java.awt.Color[r=226,g=255,b=226],text=</strong>\n" +
210 "background=java.awt.Color[r=255,g=255,b=255],text= man\n" +
213 "fontStyle=3,text=@param \n" +
214 "foreground=java.awt.Color[r=61,g=61,b=61],text=<T>\n" +
219 public void testIndentStrippingWhenFirstLineIsMostIndented() throws Exception {
220 init("public class Test {\n" +
221 "<selection> int field;\n" +
223 verifySyntaxInfo("text= \n" +
224 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=int \n" +
225 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
226 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
231 public void testIndentStrippingWhenSelectionEndIsBeforeNonWsCharactersOnTheLine() throws Exception {
232 init("public class Test {\n" +
233 "<selection> int field;\n" +
235 verifySyntaxInfo("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=int \n" +
236 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
237 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
241 public void testSlashRSeparator() throws Exception {
242 String text = "package org;\r" +
244 "public class TestClass {\r" +
248 " public int getField() {\r" +
252 initWithCustomLineSeparators(text);
253 int selectionStart = text.indexOf("public int");
254 int selectionEnd = text.indexOf('}', selectionStart);
255 myFixture.getEditor().getSelectionModel().setSelection(selectionStart, selectionEnd);
257 verifySyntaxInfo("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=public int \n" +
258 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=getField() {\n" +
261 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=return \n" +
262 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
263 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
268 public void testSlashRSlashNSeparator() throws Exception {
269 String text = "package org;\r\n" +
271 "public class TestClass {\r\n" +
275 " public int getField() {\r\n" +
276 " return field;\r\n" +
279 initWithCustomLineSeparators(text);
280 int selectionStart = text.indexOf("public int");
281 int selectionEnd = text.indexOf('}', selectionStart);
282 myFixture.getEditor().getSelectionModel().setSelection(selectionStart, selectionEnd);
284 verifySyntaxInfo("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=public int \n" +
285 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=getField() {\n" +
288 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=return \n" +
289 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
290 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
295 private String getSyntaxInfo() {
296 final StringBuilder builder = new StringBuilder();
297 final Editor editor = myFixture.getEditor();
298 String selectedText = editor.getSelectionModel().getSelectedText(true);
299 assertNotNull(selectedText);
300 final String text = StringUtil.convertLineSeparators(selectedText);
302 TextWithMarkupProcessor processor = new TextWithMarkupProcessor() {
304 void createResult(SyntaxInfo syntaxInfo, Editor editor) {
305 final ColorRegistry colorRegistry = syntaxInfo.getColorRegistry();
306 assertEquals(JBColor.BLACK, colorRegistry.dataById(syntaxInfo.getDefaultForeground()));
307 assertEquals(JBColor.WHITE, colorRegistry.dataById(syntaxInfo.getDefaultBackground()));
308 assertEquals((float)getFontSize(), syntaxInfo.getFontSize(), 0.01f);
309 syntaxInfo.processOutputInfo(new MarkupHandler() {
311 public void handleText(int startOffset, int endOffset) throws Exception {
312 builder.append("text=").append(text.substring(startOffset, endOffset)).append('\n');
316 public void handleForeground(int foregroundId) throws Exception {
317 builder.append("foreground=").append(colorRegistry.dataById(foregroundId)).append(',');
321 public void handleBackground(int backgroundId) throws Exception {
322 builder.append("background=").append(colorRegistry.dataById(backgroundId)).append(',');
326 public void handleFont(int fontNameId) throws Exception {
327 assertEquals(1, fontNameId);
331 public void handleStyle(int style) throws Exception {
332 builder.append("fontStyle=").append(style).append(',');
336 public boolean canHandleMore() {
342 SelectionModel selectionModel = editor.getSelectionModel();
343 processor.collectTransferableData(myFixture.getFile(), editor, selectionModel.getBlockSelectionStarts(), selectionModel.getBlockSelectionEnds());
345 return builder.toString();
348 private void init(String text) {
349 myFixture.configureByText(getTestName(true) + ".java", text);
350 myFixture.doHighlighting();
353 private void initWithCustomLineSeparators(final String text) {
354 myFixture.configureByText(getTestName(true) + ".java", "");
355 final DocumentImpl document = (DocumentImpl)myFixture.getEditor().getDocument();
356 document.setAcceptSlashR(true);
357 ApplicationManager.getApplication().runWriteAction(new Runnable() {
360 document.setText(text);
363 myFixture.doHighlighting();
366 private void verifySyntaxInfo(String info) {
367 assertEquals(info, getSyntaxInfo());
370 private int getFontSize() {
371 return myFixture.getEditor().getColorsScheme().getEditorFontSize();
375 protected boolean isWriteActionRequired() {