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.*;
20 import com.intellij.openapi.editor.ex.EditorEx;
21 import com.intellij.openapi.editor.impl.DocumentImpl;
22 import com.intellij.openapi.editor.richcopy.model.ColorRegistry;
23 import com.intellij.openapi.editor.richcopy.model.MarkupHandler;
24 import com.intellij.openapi.editor.richcopy.model.SyntaxInfo;
25 import com.intellij.openapi.fileEditor.FileDocumentManager;
26 import com.intellij.openapi.fileTypes.FileType;
27 import com.intellij.openapi.fileTypes.FileTypeRegistry;
28 import com.intellij.openapi.util.text.StringUtil;
29 import com.intellij.openapi.vfs.VirtualFile;
30 import com.intellij.psi.PsiFile;
31 import com.intellij.psi.PsiFileFactory;
32 import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
33 import com.intellij.ui.JBColor;
36 * @author Denis Zhdanov
37 * @since 3/27/13 11:11 AM
39 public class SyntaxInfoConstructionTest extends LightPlatformCodeInsightFixtureTestCase {
40 public void testBlockSelection() {
44 "public class TestClass {\n" +
48 " public int getField() {\n" +
54 int blockSelectionStartOffset = text.indexOf("public int");
55 Editor editor = myFixture.getEditor();
56 LogicalPosition blockSelectionStartPosition = editor.offsetToLogicalPosition(blockSelectionStartOffset);
57 LogicalPosition blockSelectionEndPosition = new LogicalPosition(
58 blockSelectionStartPosition.line + 2,
59 editor.offsetToLogicalPosition(text.indexOf('{', blockSelectionStartOffset)).column + 1);
60 editor.getSelectionModel().setBlockSelection(blockSelectionStartPosition, blockSelectionEndPosition);
62 verifySyntaxInfo("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=public int \n" +
63 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=getField() {\n" +
67 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=return \n" +
68 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
69 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
75 public void testColumnModeBlockSelection() {
79 "public class TestClass {\n" +
83 " public int getField() {\n" +
89 int blockSelectionStartOffset = text.indexOf("public int");
90 Editor editor = myFixture.getEditor();
91 ((EditorEx) editor).setColumnMode(true);
92 LogicalPosition blockSelectionStartPosition = editor.offsetToLogicalPosition(blockSelectionStartOffset);
93 LogicalPosition blockSelectionEndPosition = new LogicalPosition(
94 blockSelectionStartPosition.line + 2,
95 editor.offsetToLogicalPosition(text.indexOf('{', blockSelectionStartOffset)).column + 1);
96 editor.getSelectionModel().setBlockSelection(blockSelectionStartPosition, blockSelectionEndPosition);
98 verifySyntaxInfo("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=public int \n" +
99 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=getField() {\n" +
103 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=return \n" +
104 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
105 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
111 public void testColumnModeBlockSelectionWithGaps() {
113 "public class TestClass {\n" +
117 " int otherField;\n" +
121 int blockSelectionStartOffset = text.indexOf("int");
122 Editor editor = myFixture.getEditor();
123 ((EditorEx) editor).setColumnMode(true);
124 LogicalPosition blockSelectionStartPosition = editor.offsetToLogicalPosition(blockSelectionStartOffset);
125 LogicalPosition blockSelectionEndPosition = new LogicalPosition(blockSelectionStartPosition.line + 2, blockSelectionStartPosition.column + 16);
126 editor.getSelectionModel().setBlockSelection(blockSelectionStartPosition, blockSelectionEndPosition);
128 verifySyntaxInfo("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=int \n" +
129 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
130 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
135 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=int \n" +
136 "foreground=java.awt.Color[r=102,g=14,b=122],text=otherField\n" +
137 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n");
140 public void testRegularSelection() {
141 // We want to exclude unnecessary indents from the pasted results.
145 "public class TestClass {\n" +
149 " public int getField() {\n" +
155 int selectionStart = text.indexOf("public int");
156 int selectionEnd = text.indexOf('}', selectionStart) + 1;
157 SelectionModel selectionModel = myFixture.getEditor().getSelectionModel();
158 selectionModel.setSelection(selectionStart, selectionEnd);
160 String expected = "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=public int \n" +
161 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=getField() {\n" +
164 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=return \n" +
165 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
166 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
170 verifySyntaxInfo(expected);
172 selectionModel.setSelection(selectionStart - 2, selectionEnd);
173 verifySyntaxInfo(expected);
175 selectionModel.setSelection(selectionStart - 4, selectionEnd);
176 verifySyntaxInfo(expected);
179 public void testIncorrectFirstLineCalculationOffset() {
180 init("\"tr\" #> <selection>template.statusList.sortBy</selection>(_.index).map(fromStatus =>");
182 verifySyntaxInfo("fontStyle=0,text=template.statusList.sortBy\n");
185 public void testJavadoc() {
189 "import java.io.Serializable;\n" +
192 " * Code in <code>here</code>\n" +
193 " * <strong>Hi</strong> man\n" +
195 " </selection>*/\n" +
196 "public interface SampleTest<T> extends Serializable {\n" +
197 " boolean isNotNull();\n" +
201 verifySyntaxInfo("foreground=java.awt.Color[r=128,g=128,b=128],fontStyle=2,text=/**\n" +
203 "text= * Code in \n" +
204 "background=java.awt.Color[r=226,g=255,b=226],text=<code>\n" +
205 "background=java.awt.Color[r=255,g=255,b=255],text=here\n" +
206 "background=java.awt.Color[r=226,g=255,b=226],text=</code>\n" +
207 "background=java.awt.Color[r=255,g=255,b=255],text=\n" +
210 "background=java.awt.Color[r=226,g=255,b=226],text=<strong>\n" +
211 "background=java.awt.Color[r=255,g=255,b=255],text=Hi\n" +
212 "background=java.awt.Color[r=226,g=255,b=226],text=</strong>\n" +
213 "background=java.awt.Color[r=255,g=255,b=255],text= man\n" +
216 "fontStyle=3,text=@param \n" +
217 "foreground=java.awt.Color[r=61,g=61,b=61],text=<T>\n" +
222 public void testIndentStrippingWhenFirstLineIsMostIndented() throws Exception {
223 init("public class Test {\n" +
224 "<selection> int field;\n" +
226 verifySyntaxInfo("text= \n" +
227 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=int \n" +
228 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
229 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
234 public void testIndentStrippingWhenSelectionEndIsBeforeNonWsCharactersOnTheLine() throws Exception {
235 init("public class Test {\n" +
236 "<selection> int field;\n" +
238 verifySyntaxInfo("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=int \n" +
239 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
240 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
244 public void testSlashRSeparator() throws Exception {
245 String text = "package org;\r" +
247 "public class TestClass {\r" +
251 " public int getField() {\r" +
255 initWithCustomLineSeparators(text);
256 int selectionStart = text.indexOf("public int");
257 int selectionEnd = text.indexOf('}', selectionStart);
258 myFixture.getEditor().getSelectionModel().setSelection(selectionStart, selectionEnd);
260 verifySyntaxInfo("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=public int \n" +
261 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=getField() {\n" +
264 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=return \n" +
265 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
266 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
271 public void testSlashRSlashNSeparator() throws Exception {
272 String text = "package org;\r\n" +
274 "public class TestClass {\r\n" +
278 " public int getField() {\r\n" +
279 " return field;\r\n" +
282 initWithCustomLineSeparators(text);
283 int selectionStart = text.indexOf("public int");
284 int selectionEnd = text.indexOf('}', selectionStart);
285 myFixture.getEditor().getSelectionModel().setSelection(selectionStart, selectionEnd);
287 verifySyntaxInfo("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=public int \n" +
288 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=getField() {\n" +
291 "foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=return \n" +
292 "foreground=java.awt.Color[r=102,g=14,b=122],text=field\n" +
293 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=;\n" +
298 public void testNonPhysicalFile() throws Exception {
299 String fileName = "Test.java";
300 FileType fileType = FileTypeRegistry.getInstance().getFileTypeByFileName(fileName);
301 PsiFile psiFile = PsiFileFactory.getInstance(getProject()).createFileFromText(fileName, fileType, "class Test {}", 0, false);
302 VirtualFile virtualFile = psiFile.getViewProvider().getVirtualFile();
303 Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
304 assertNotNull(document);
305 EditorFactory editorFactory = EditorFactory.getInstance();
306 Editor editor = editorFactory.createViewer(document, getProject());
308 editor.getSelectionModel().setSelection(0, document.getTextLength());
309 String syntaxInfo = getSyntaxInfo(editor, psiFile);
310 assertEquals("foreground=java.awt.Color[r=0,g=0,b=128],fontStyle=1,text=class \n" +
311 "foreground=java.awt.Color[r=0,g=0,b=0],fontStyle=0,text=Test {}\n", syntaxInfo);
314 editorFactory.releaseEditor(editor);
318 private String getSyntaxInfo() {
319 return getSyntaxInfo(myFixture.getEditor(), myFixture.getFile());
322 private static String getSyntaxInfo(Editor editor, PsiFile psiFile) {
323 final StringBuilder builder = new StringBuilder();
324 SelectionModel selectionModel = editor.getSelectionModel();
325 String selectedText = selectionModel.getSelectedText(true);
326 assertNotNull(selectedText);
327 final String text = StringUtil.convertLineSeparators(selectedText);
329 TextWithMarkupProcessor processor = new TextWithMarkupProcessor() {
331 void createResult(SyntaxInfo syntaxInfo, Editor editor) {
332 final ColorRegistry colorRegistry = syntaxInfo.getColorRegistry();
333 assertEquals(JBColor.BLACK, colorRegistry.dataById(syntaxInfo.getDefaultForeground()));
334 assertEquals(JBColor.WHITE, colorRegistry.dataById(syntaxInfo.getDefaultBackground()));
335 assertEquals((float)editor.getColorsScheme().getEditorFontSize(), syntaxInfo.getFontSize(), 0.01f);
336 syntaxInfo.processOutputInfo(new MarkupHandler() {
338 public void handleText(int startOffset, int endOffset) throws Exception {
339 builder.append("text=").append(text.substring(startOffset, endOffset)).append('\n');
343 public void handleForeground(int foregroundId) throws Exception {
344 builder.append("foreground=").append(colorRegistry.dataById(foregroundId)).append(',');
348 public void handleBackground(int backgroundId) throws Exception {
349 builder.append("background=").append(colorRegistry.dataById(backgroundId)).append(',');
353 public void handleFont(int fontNameId) throws Exception {
354 assertEquals(1, fontNameId);
358 public void handleStyle(int style) throws Exception {
359 builder.append("fontStyle=").append(style).append(',');
363 public boolean canHandleMore() {
369 processor.collectTransferableData(psiFile, editor, selectionModel.getBlockSelectionStarts(), selectionModel.getBlockSelectionEnds());
371 return builder.toString();
374 private void init(String text) {
375 myFixture.configureByText(getTestName(true) + ".java", text);
376 myFixture.doHighlighting();
379 private void initWithCustomLineSeparators(final String text) {
380 myFixture.configureByText(getTestName(true) + ".java", "");
381 final DocumentImpl document = (DocumentImpl)myFixture.getEditor().getDocument();
382 document.setAcceptSlashR(true);
383 ApplicationManager.getApplication().runWriteAction(new Runnable() {
386 document.setText(text);
389 myFixture.doHighlighting();
392 private void verifySyntaxInfo(String info) {
393 assertEquals(info, getSyntaxInfo());
397 protected boolean isWriteActionRequired() {